在上一篇文章中簡單了介紹了下什麼ko(後文中都已ko來代替knockout.js)和一些簡單的ko的使用方法下面我將介紹在實際的項目中經常使用到的幾種綁定方式和方法.html
在開始以前先拿一個dome來回顧下ko的綁定方式吧。廢話很少說上代碼。api
var BetterListModel = function () { this.itemToAdd = ko.observable(""); this.allItems = ko.observableArray(["Fries", "Eggs Benedict", "Ham", "Cheese"]); // 初始化數據 this.selectedItems = ko.observableArray(["Ham"]); // 初始化選定項 this.addItem = function () { if ((this.itemToAdd() != "") && (this.allItems.indexOf(this.itemToAdd()) < 0)) // 判斷不爲空而且不存在重複的數據 this.allItems.push(this.itemToAdd()); this.itemToAdd(""); // 清空文本框內容綁定 }; this.removeSelected = function () { this.allItems.removeAll(this.selectedItems()); this.selectedItems([]); //清空集合 }; this.sortItems = function() { this.allItems.sort(); }; }; ko.applyBindings(new BetterListModel());
簡單說明下。建立了一個對象模型。裏面有一些簡單屬性和複雜屬性,還有一個行爲事件(以面向對象來理解會很簡單) 若是看過以前的文章在看這個相信會一目瞭然.app
下面給出dom的綁定dom
<form data-bind="submit:addItem"> Add item: <input type="text" data-bind='value:itemToAdd, valueUpdate: "afterkeydown"' /> <button type="submit" data-bind="enable: itemToAdd().length > 0">Add</button> </form> <p>Your values:</p> <select multiple="multiple" height="5" data-bind="options:allItems, selectedOptions:selectedItems"> </select> <div> <button data-bind="click: removeSelected, enable: selectedItems().length > 0">Remove</button> <button data-bind="click: sortItems, enable: allItems().length > 1">Sort</button> </div>
照例也給出調試的地址 http://jsfiddle.net/rniemeyer/aDahT/ 函數
上面的內容呢主要仍是用來回顧以前的東西。下面開始本節的內容。先從表單的綁定提及吧。先直接給出來表單模型的定義代碼this
var viewModel = {
stringValue : ko.observable("Hello"),
passwordValue : ko.observable("mypass"),
booleanValue : ko.observable(true),
optionValues : ["Alpha", "Beta", "Gamma"],
selectedOptionValue : ko.observable("Gamma"),
multipleSelectedOptionValues : ko.observable(["Alpha"]),
radioSelectedOptionValue : ko.observable("Beta")
};
ko.applyBindings(viewModel);
上面的模型定了基本都是定一些了些屬性和一些默認值,固然你也能夠動態的從後臺拿到這個數據,而後直接更新對象的模型屬性便可,像這樣 viewModel.optionValues(youdata) spa
下面繼續說前臺的綁定,這裏先直接給出綁定的代碼。.net
<div class="readout"> <h3>What's in the model?</h3> <table> <tr> <td class="label">Text value:</td> <td data-bind="text: stringValue"></td> </tr> <tr> <td class="label">Password:</td> <td data-bind="text: passwordValue"></td> </tr> <tr> <td class="label">Bool value:</td> <td data-bind='text: booleanValue() ? "True" : "False"'></td> </tr> <tr> <td class="label">Selected option:</td> <td data-bind="text: selectedOptionValue"></td> </tr> <tr> <td class="label">Multi-selected options:</td> <td data-bind="text: multipleSelectedOptionValues"></td> </tr> <tr> <td class="label">Radio button selection:</td> <td data-bind="text: radioSelectedOptionValue"></td> </tr> </table> </div> <h3>HTML controls</h3> <table> <tr> <td class="label">Text value (updates on change):</td> <td><input data-bind="value: stringValue" /></td> </tr> <tr> <td class="label">Text value (updates on keystroke):</td> <td><input data-bind='value: stringValue, valueUpdate: "afterkeydown"' /></td> </tr> <tr> <td class="label">Text value (multi-line):</td> <td><textarea data-bind="value: stringValue"> </textarea></td> </tr> <tr> <td class="label">Password:</td> <td><input type="password" data-bind="value: passwordValue" /></td> </tr> <tr> <td class="label">Checkbox:</td> <td><input type="checkbox" data-bind="checked: booleanValue" /></td> </tr> <tr> <td class="label">Drop-down list:</td> <td><select data-bind="options: optionValues, value: selectedOptionValue"></select></td> </tr> <tr> <td class="label">Multi-select drop-down list:</td> <td><select multiple="multiple" data-bind="options: optionValues, selectedOptions: multipleSelectedOptionValues"></select></td> </tr> <tr> <td class="label">Radio buttons:</td> <td> <label><input type="radio" value="Alpha" data-bind="checked: radioSelectedOptionValue" />Alpha</label> <label><input type="radio" value="Beta" data-bind="checked: radioSelectedOptionValue" />Beta</label> <label><input type="radio" value="Gamma" data-bind="checked: radioSelectedOptionValue" />Gamma</label> </td> </tr> </table>
調試的地址爲 http://jsfiddle.net/rniemeyer/ZbrB7/調試
在這我就詳細說明下具體的綁定究竟是什麼表明什麼意思。其實你們應該從字面上均可以簡單的看出來這些綁定是幹什麼的。可是爲了讓初學者看的更明白些,我仍是準備說明一下。code
1:data-bind="text:你要綁定的字段名稱" //這裏綁定是指的顯示的文本信息的綁定.
2:data-bind="value:你要綁定的字段名稱"//文本框值的綁定.
3:data-bind="checked:true或者false或者是表達式"//這個綁定是針對單選和多選框的綁定方法。用來指明是否被選中.
4:data-bind="options:選項的集合,selectedOptions:默認選中的值"//綁定select的options ,selectedOptions用來指定默認選中的值.
上面的4種綁定方式呢,是比較經常使用的表單元素的綁定,PS:(若是你須要用表達式動態綁定的時候,你須要在要判斷的元素後面加上小括號).在這裏我提一個問題。若是須要經過一個斷定字段來判斷後面的內容是否綁定要怎麼作?這裏我先賣個關子,大家能夠先思考下,後面我會給出說明,若是在後面的dome中若是出現新的綁定方式我會再次說明.
<td data-bind='text: booleanValue() ? "True" : "False"'></td>
下面繼續介紹如何綁定數據集合的綁定。也順便引出新的綁定方式foreach綁定。
// 定義一我的的對象。這個對象有兩個字段 一個是名字一個是子節點 默認有兩個構造函數的參數. var Person = function(name, children) { this.name = name; this.children = ko.observableArray(children); this.addChild = function() { this.children.push("New child"); }.bind(this); } // 在定義一個頁面UI的模型對象,模型對象people裏面放入person集合 var viewModel = { people: [ new Person("Annabelle", ["Arnie", "Anders", "Apple"]), new Person("Bertie", ["Boutros-Boutros", "Brianna", "Barbie", "Bee-bop"]), new Person("Charles", ["Cayenne", "Cleopatra"]) ], showRenderTimes: ko.observable(false) }; ko.applyBindings(viewModel);
這裏直接給出dom綁定下面在說明
<h2>People</h2> <ul data-bind="foreach: people"> <li> <div> <span data-bind="text: name"> </span> has <span data-bind='text: children().length'> </span> children: <a href='#' data-bind='click: addChild '>Add child</a> <span class='renderTime' data-bind='visible: $root.showRenderTimes'> (person rendered at <span data-bind='text: new Date().getSeconds()' > </span>) </span> </div> <ul data-bind="foreach: children"> <li> <span data-bind="text: $data"> </span> <span class='renderTime' data-bind='visible: $root.showRenderTimes'> (child rendered at <span data-bind='text: new Date().getSeconds()' > </span>) </span> </li> </ul> </li> </ul> <label><input data-bind='checked: showRenderTimes' type='checkbox' /> Show render times</label>
調試的 地址是 http://jsfiddle.net/rniemeyer/GSvnh/
這裏的data-bind="foreach:你要循環的集合"//在foreach包裹的區域內。你能夠綁定對應的單個對象的具體字段內容。若是裏面裏面的某一個字段是一個集合你還能夠繼續嵌套循環來綁定數據如上,PS( 這裏順便說一嘴。就是說若是你須要在子循環裏面,綁定父循環的數據你須要像這樣來綁定,$.parent.父節點字段) 上面表明中出現的$.data就表明當前的綁定對象自己,而$.root則表明模型裏面最高層對象.
這裏的foreach 綁定也就是用的最多的綁定,用起來也很簡單,可是它有一個問題,就是他的綁定須要指定一個父容器也就是說要綁到具體的dom元素上,可是有時候我並不想綁定到具體的dom對象上哪怎麼辦呢?。那就沒辦法解決嗎?
答案固然是否認的。KO官方給出 了比較另類可是很實用的的綁定方式用來解決這個問題,我以爲這算是一個語法糖了。
就以上面的綁定爲例,你能夠這麼寫
<div class='liveExample'> <h2>People</h2> <!--ko foreach:people--> <li> <div> <span data-bind="text: name"> </span> has <span data-bind='text: children().length'> </span> children: <a href='#' data-bind='click: addChild '>Add child</a> <span class='renderTime' data-bind='visible: $root.showRenderTimes'> (person rendered at <span data-bind='text: new Date().getSeconds()' > </span>) </span> </div> <ul data-bind="foreach: children"> <li> <span data-bind="text: $data"> </span> <span class='renderTime' data-bind='visible: $root.showRenderTimes'> (child rendered at <span data-bind='text: new Date().getSeconds()' > </span>) </span> </li> </ul> </li> <!--/ko--> <label><input data-bind='checked: showRenderTimes' type='checkbox' /> Show render times</label> </div>
相信你們一看就能明白上面代碼的意思。只是把對應的<
ul
data-bind
=
"foreach: people"
> </ul>綁定具體的dom元素換成了看起來像註釋的綁定方式 <!--foreach:people--><!--/ko-->,兩種綁定方式的效果是同樣的,可是第二種綁定方式我比較推薦。由於它用起來會更加的靈活多變。
在這我在順便回答下,上面我提成的問題。也就是如何經過綁定的字段判斷後面的內容是否須要綁定呢?下面給出代碼
<ul data-bind="foreach: planets"> <li> Planet: <b data-bind="text: name"> </b> <div data-bind="if: capital"> Capital: <b data-bind="text: capital.cityName"> </b> </div> </li> </ul> <script> ko.applyBindings({ planets: [ { name: 'Mercury', capital: null }, { name: 'Earth', capital: { cityName: 'Barnsley' } } ] }); </script>
在data-bind中有個if的綁定方式。咱們能夠用這個來解決我剛纔說過的問題。與之對應的還有另外一種綁定方法就是ifnot 下面給出代碼你們能夠對照着理解
<div data-bind="ifnot: someProperty">...</div>
看到這,我相信你已經理解的ko的基本使用的方法,如今你能夠在你的項目中使用KO來綁定數據了。
關於更多細枝末節的問題呢我會繼續在後面的章節裏來講明。