1. 程式人生 > 實用技巧 >使用Bootstrap和#KnockoutJS將單選按鈕替換為按鈕組

使用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