使用Bootstrap和#KnockoutJS將單選按鈕替換為按鈕組
問題
單選按鈕很難看到,不容易選擇,讓我們面對它,相當平凡。您可能想用一組具有相同功能的按鈕來替換這些單選按鈕,例如,在任何給定的時間只能選擇其中一個選項。
解決方案
利用Bootstrap,它為按鈕、警告框、表格、表單等提供了許多令人難以置信的樣式元件,常規的單選按鈕將被一個按鈕組取代(見下面的截圖)。js將用於建立一個定製的資料繫結,它將使這組按鈕像常規的單選按鈕一樣工作(當然有更好的外觀)。
這個例子假設您對Bootstrap和Knockout.js都有基本的瞭解。
本例使用的版本是Bootstrap的3.3.4和Knockout.js的3.3。這個示例應該與這些框架的舊版本相容。
討論
在開始之前,必須設定所需的框架。Bootstrap可以通過他們的CDN安裝或下載。這個例子將使用CDN;但是,我建議您使用最適合您需要的選項。js已經被下載並儲存到與示例相同的位置。確保根據專案的位置更新此位置。最後,在敲除定製繫結中使用了一點jQuery。再一次,這個例子利用了CDN;但是,如果你喜歡,你可以下載幷包含它。
要使這個示例工作,它需要兩個條件。一組按鈕,如果它們是單選按鈕,將包含哪些選項,以及將在資料繫結中使用的敲除可觀察值。這個可觀察物件將包含選中的選項。下面包含HTML標記和非常基本的Knockout ViewModel。
隱藏,縮小,複製程式碼<html><head> <linkrel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> </head> <body> <divclass="btn-group"> <buttontype="button"class="btn btn-default"data-bind="radioButtonGroup: selectedOption, radioValue: 'option1'">Option 1</button> <buttontype="button"class="btn btn-default"data-bind="radioButtonGroup: selectedOption, radioValue: 'option2'">Option 2</button> <buttontype="button"class="btn btn-default"data-bind="radioButtonGroup: selectedOption, radioValue: 'option3'">Option 3</button> </div> <scriptsrc="knockout.js"></script> <scriptsrc="http://code.jquery.com/jquery-2.1.3.min.js"></script> <script> function ViewModel() { var self = this; self.selectedOption = ko.observable(); }; var viewModel = new ViewModel(); ko.applyBindings(viewModel); </script> </body> </html>
這個例子現在還不能工作。如果仔細觀察,就會發現每個HTML按鈕都包含一個名為radioButtonGroup的資料繫結(馬上就會定義)。這是將完成我們的按鈕組的定製資料繫結。提供給新資料繫結的是可觀察變數,它被恰當地命名為selectedOption。第二個值也被命名為radioValue。這應該設定為使用者按下按鈕時希望selectedOption變數包含的值。
要完成這個示例,需要建立自定義繫結。在ko下新增自定義繫結。bindingHandlers名稱空間。繫結處理程式是通過建立init和update函式定義的。兩者都是可選的,但至少必須定義一個。當Knockout是繫結到頁面的第一個資料時,將呼叫init函式。你可以在這裡建立事件監聽器等等。每次值更改時(包括第一次載入時)都會呼叫update函式。如果您希望在每次值更改時執行特定的操作,則將使用此函式。
radioButtonGroup自定義繫結只需要init函式,因為單擊事件的事件監聽器將用於跟蹤所有更改。下面的JavaScript程式碼應該在包含Knockout框架之後,但在定義ViewModel和應用Knockout繫結之前放置(或從一個單獨的檔案中包含)。
隱藏,縮小,複製程式碼<script> ko.bindingHandlers.radioButtonGroup = { init: function (element, valueAccessor, allBindings, viewModel, context) { var $buttons, $element, observable; observable = valueAccessor(); if (!ko.isWriteableObservable(observable)) { throw "You must pass an observable or writeable computed"; } $element = $(element); if ($element.hasClass("btn")) { $buttons = $element; } else { $buttons = $(".btn", $element); } elementBindings = allBindings(); $buttons.each(function () { var $btn, btn, radioValue; btn = this; $btn = $(btn); radioValue = elementBindings.radioValue || $btn.attr("data-value") || $btn.attr("value") || $btn.text(); $btn.on("click", function () { observable(ko.utils.unwrapObservable(radioValue)); }); return ko.computed({ disposeWhenNodeIsRemoved: btn, read: function () { $btn.toggleClass("active", observable() === ko.utils.unwrapObservable(radioValue)); $btn.toggleClass("btn-info", observable() === ko.utils.unwrapObservable(radioValue)); } }); }); } }; </script>
init函式接受5個引數。被資料繫結的元素,也是資料繫結的變數,這個元素上的所有其他繫結,整個ViewModel(儘管這是不贊成的),還有bindingContext,這是通過使用bindingContext.$data來訪問ViewModel的新方法。
在init函式內部,它首先驗證它正在處理一個可觀察屬性。通過使用帶有資料繫結的HTML元素(和一些jQuery),可以找到相關的按鈕並存儲在一個變數中。然後迴圈使用這些按鈕,並偵聽單擊事件。當它發生時,與資料繫結值相關聯的可觀察屬性將使用所選選項更新。最後定義一個計算變數,如果可觀察物件的值等於按鈕的值,則新增類active和btn-info來標識當前選擇的按鈕。
這就完成了本示例,一如既往,您可以在GitHub上找到完整的原始碼。
本文轉載於:http://www.diyabc.com/frontweb/news14015.html