KnockoutJS 3.X API 第七章 其他技術(shù)(5) 使用其他事件處理程序
在大多數(shù)情況下,數(shù)據(jù)綁定屬性提供了一種干凈和簡(jiǎn)潔的方式來(lái)綁定到視圖模型。 然而,事件處理是一個(gè)常常會(huì)導(dǎo)致詳細(xì)數(shù)據(jù)綁定屬性的領(lǐng)域,因?yàn)槟涿瘮?shù)通常是傳遞參數(shù)的推薦技術(shù)。 例如:
<a href="#" data-bind="click: function() { viewModel.items.remove($data); }"> remove </a>
作為替代,Knockout提供了兩個(gè)幫助函數(shù),它們?cè)试S您標(biāo)識(shí)與DOM元素關(guān)聯(lián)的數(shù)據(jù):
ko.dataFor(element)- 返回可用于與元素綁定的數(shù)據(jù)ko.contextFor(element)- 返回DOM元素可用的整個(gè)綁定上下文
這些幫助函數(shù)可以在事件處理程序中使用,這些事件處理程序使用類似于jQuery的綁定或單擊的方式地附加。 上面的函數(shù)可以連接到每個(gè)鏈接一個(gè)刪除類,如:
$(".remove").click(function () {
viewModel.items.remove(ko.dataFor(this));
});更好的是,這種技術(shù)可以用于支持事件委托。 jQuery live / delegate / on函數(shù)是一個(gè)簡(jiǎn)單的方法來(lái)實(shí)現(xiàn)這一點(diǎn):
$(".container").on("click", ".remove", function() {
viewModel.items.remove(ko.dataFor(this));
});現(xiàn)在,單個(gè)事件處理程序在更高級(jí)別附加,并處理與remove類的任何鏈接的點(diǎn)擊。 此方法還具有自動(dòng)處理動(dòng)態(tài)添加到文檔的附加鏈接(可能是由于項(xiàng)目添加到observableArray的結(jié)果)的額外好處。
示例:嵌套子節(jié)點(diǎn)
此示例顯示父級(jí)和子級(jí)的多個(gè)級(jí)別上的“add”和“remove”鏈接,每個(gè)類型的鏈接具有單個(gè)處理程序。
UI源碼:
<ul id="people" data-bind='template: { name: "personTmpl", foreach: people }'> </ul> <script id="personTmpl" type="text/html"> <li> <a class="remove" href="#"> x </a> <span data-bind='text: name'></span> <a class="add" href="#"> add child </a> <ul data-bind='template: { name: "personTmpl", foreach: children }'></ul> </li> </script>
視圖模型源碼:
var Person = function(name, children) { this.name = ko.observable(name); this.children = ko.observableArray(children || []); }; var PeopleModel = function() { this.people = ko.observableArray([ new Person("Bob", [ new Person("Jan"), new Person("Don", [ new Person("Ted"), new Person("Ben", [ new Person("Joe", [ new Person("Ali"), new Person("Ken") ]) ]), new Person("Doug") ]) ]), new Person("Ann", [ new Person("Eve"), new Person("Hal") ]) ]); this.addChild = function(name, parentArray) { parentArray.push(new Person(name)); }; }; ko.applyBindings(new PeopleModel()); //attach event handlers $("#people").on("click", ".remove", function() { //retrieve the context var context = ko.contextFor(this), parentArray = context.$parent.people || context.$parent.children; //remove the data (context.$data) from the appropriate array on its parent (context.$parent) parentArray.remove(context.$data); return false; }); $("#people").on("click", ".add", function() { //retrieve the context var context = ko.contextFor(this), childName = context.$data.name() + " child", parentArray = context.$data.people || context.$data.children; //add a child to the appropriate parent, calling a method off of the main view model (context.$root) context.$root.addChild(childName, parentArray); return false; });
無(wú)論嵌套鏈接如何嵌套,處理程序總是能夠識(shí)別和操作適當(dāng)?shù)臄?shù)據(jù)。 使用這種技術(shù),我們可以避免將處理程序附加到每個(gè)鏈接的開(kāi)銷,并可以保持標(biāo)記清潔和簡(jiǎn)潔。

浙公網(wǎng)安備 33010602011771號(hào)