June 6, 2013

KnockoutJS - radio button應用(1)

多個radio button
radio button常見的應用之一就是在多個選項中讓使用者單選出其中一個項目。與checkbox相同,radio button也是使用checked binding來讀取或寫入當前使用者所選擇的項目。對radio button來說,因為所選擇的項目只有一個,所以ViewModel用於data binding的屬性是observable而不是observableArray。
<label>
    <input name="aspnet" type="radio" value="webforms" data-bind="checked: technique" />ASP.NET Web Forms
</label>
<label>
    <input name="aspnet" type="radio" value="mvc" data-bind="checked: technique" />ASP.NET MVC
</label>
<label>
    <input name="aspnet" type="radio" value="webapi" data-bind="checked: technique" />ASP.NET Web API
</label>
<div data-bind="text: technique"></div>
function ViewModel() {
    var self = this;
    self.technique = ko.observable("");
}

ko.applyBindings(new ViewModel());

執行結果



顯示radio button選項文字
從上面的執行結果可以知道,當使用者選擇ASP.NET Web Forms,下方顯示的是webforms,也就是radio button之。這值通常是我們取得後要更新回後端用的,對使用者而言未必是有意義的資料。在某些情況下,使用者想看到並不是radio button的值,而是選項的名稱,如ASP.NET Web Forms,這時我們就必須在使用者按下選項後,即時抓取radio button後面的選項文字來顯示給使用者知道。
<label>
    <input name="aspnet" type="radio" value="webforms" data-bind="checked: technique" />ASP.NET Web Forms
</label>
<label>
    <input name="aspnet" type="radio" value="mvc" data-bind="checked: technique" />ASP.NET MVC
</label>
<label>
    <input name="aspnet" type="radio" value="webapi" data-bind="checked: technique" />ASP.NET Web API
</label>
<div data-bind="text: techniqueText"></div>
function ViewModel() {
    var self = this;
    self.technique = ko.observable("");
    self.technique.subscribe(function (newValue) {
        self.techniqueText($("input[name=aspnet]:checked").parent().contents().filter(function () {
            return this.nodeType == 3;
        }).text());
    });

    self.techniqueText = ko.observable("");
}

ko.applyBindings(new ViewModel());

與之前的例子不同的是,我們新增了一個techniqueText屬性值用來顯示使用者所選擇的選項文字。除此之外,我們利用subscribe函式訂閱technique屬性值的變動,jQuery會取得被選取的radio button後方的選項文字。

執行結果


上述方法雖然可行,但如果在選項文字後方又有其它不必要顯示出來的文字的話(如括號註解說明)也會一併顯示出來。

另一個可行的方法則是將選項文字加上標籤如span,再搭配jQuery的next函式取得radio button的下一個element(span標籤),即可取得選項文字。
<label>
    <input name="aspnet" type="radio" value="webforms" data-bind="checked: technique" /><span>ASP.NET Web Form</span></label>
<label>
    <input name="aspnet" type="radio" value="mvc" data-bind="checked: technique" /><span>ASP.NET MVC</span>
</label>
<label>
    <input name="aspnet" type="radio" value="webapi" data-bind="checked: technique" /><span>ASP.NET Web API</span>
</label>
<div data-bind="text: techniqueText"></div>
function ViewModel() {
    var self = this;
    self.technique = ko.observable("");
    self.technique.subscribe(function (newValue) {
        self.techniqueText($("input[name=aspnet]:checked").next().text());
    });

    self.techniqueText = ko.observable("");
}

ko.applyBindings(new ViewModel());

執行結果



延伸閱讀
KnockoutJS - radio button應用(2)