針對checkbox, radio等HTML元素,knockout.js提供了checked繫結。有三種應用方式:

  1. 配合多個radio,使用相同的name形成多選一,每個radio有不同的value,KO會將被點選radio的value設成到指定的ViewModel屬性上;而當ViewModel屬性改變時,也會改變radio的點選狀態。
    <input type="radio" name="boo" value="A" data-bind="checked: someProp" />
    <input type="radio" name="boo" value="B" data-bind="checked: someProp" />
  2. 搭配單一checkbox,對應到ViewModel的Boolean屬性。當勾選時,該屬性為true、取消勾選時為false。反之,改變屬性的true/false也會反應到checkbox上。
    <input type="checkbox" data-bind="checked: someProp" />
  3. 搭配多個checkbox, 對應到ViewModel的ko.observableArray陣列,勾選結果會繫結成一個陣列,如同CheckBoxList效果,頗為犀利。例如下例的三個checkbox
    <input type="checkbox" data-bind="checked: cbxItems" value="PC" />PC
    <input type="checkbox" data-bind="checked: cbxItems" value="NB" />NB
    <input type="checkbox" data-bind="checked: cbxItems" value="Phone" />Phone

    若勾選PC及NB,則cbxItems陣列會有兩個元素"PC"、"NB"

範例10的介面如下: 線上展示

勾選電話或Email RadioBox會反應到ViewModel的contOption屬性,而該屬性又繫結到下方<select>,所以點選"電話" RadioBox 會使下拉選單切換到"電話"選項;將下拉選單選項換成"Email",RadioBox也會切到"Email"上,不用花什麼功夫就完成二者間的連動,頗為神奇。

單一Checkbox繫結到Boolean屬性singleCbx上,最下方我弄了一個顯示全部ViewModel屬性的檢視區,用以即時觀看屬性變化。

多Checkbox繫結到陣列的方式也很實用,ViewModel端可直接透過陣列取得使用者輸入結果,在屬性檢視區中,我用data-bind="foreach: cbxItems"將陣列元素內容顯示出來,試著任意勾選PC、NB、Phone,馬上能觀察到cbxItems的變化。

曾經DIY搞過類似把戲的老鳥此刻心情複雜,一方面讚嘆KO的神奇,卻也為過去嘔心瀝血累積的JavaScript程式庫化為廢柴而感傷,還要為自己的工作可能明天就被小伙子拿著knockout.js搶走擔憂,驚喜哀憂交雜,不禁流下兩行清淚~~~

完整程式碼如下:

<!DOCTYPE html>
 
<html>
<head>
    <title>Lab 9 - checked繫結</title>
    <script src="../Scripts/jquery-1.7.2.js"></script>
    <script src="../Scripts/knockout-2.1.0.debug.js"></script>
    <script>
        function MyViewModel() {
            var self = this;
            //Radio對應到Value值
            self.contOption = ko.observable("phone");
            //單一Checkbox對應到true/false
            self.singleCbx = ko.observable(true);
            //多個Checkbox對應到Value值組成的字串陣列
            self.cbxItems = ko.observableArray(["PC", "NB"]);
        }
 
        $(function () {
            ko.applyBindings(new MyViewModel());
        });
    </script>
    <style>
        body, input
        {
            font-size: 9pt;
        }
        fieldset
        {
            margin-top: 10px;
            width: 200px;
            padding: 5px;
        }
        dt, dd
        {
            float: left;
            width: 80px;
            height: 20px;
        }
    </style>
</head>
<body>
    <div>
        連絡方式選擇: 
        <input type="radio" name="contactOption" value="phone" data-bind="checked: contOption" />
        電話
        <input type="radio" name="contactOption" value="email" data-bind="checked: contOption" />
        Email
    </div>
    <div>
        (與下拉選單連動: 
        <select data-bind="value: contOption">
            <option value="phone">電話</option>
            <option value="email">Email</option>
        </select>)
    </div>
 
    <div>
        單一Checkbox:
        <input type="checkbox" data-bind="checked: singleCbx" />
    </div>
 
    <div>
        多Checkbox對應陣列: 
        <input type="checkbox" data-bind="checked: cbxItems" value="PC" />PC
        <input type="checkbox" data-bind="checked: cbxItems" value="NB" />NB
        <input type="checkbox" data-bind="checked: cbxItems" value="Phone" />Phone
    </div>
 
    <fieldset>
        <legend>物件屬性檢視</legend>
        <dl>
            <dt>contOption屬性</dt>
            <dd data-bind="text: contOption"></dd>
            <dt>singleCbx屬性</dt>
            <dd data-bind="text: singleCbx"></dd>
            <dt>cbxItems屬性</dt>
            <dd>
                <div data-bind="foreach: cbxItems">
                    <span data-bind="text: $data"></span>
                </div>
            </dd>
        </dl>
    </fieldset>
</body>
</html>
[KO系列]
http://www.darkthread.net/kolab/labs/default.aspx?m=post

Comments

Be the first to post a comment

Post a comment