在大多數狀況下,數據綁定屬性提供了一種乾淨和簡潔的方式來綁定到視圖模型。 然而,事件處理是一個經常會致使詳細數據綁定屬性的領域,由於匿名函數一般是傳遞參數的推薦技術。 例如:html
<a href="#" data-bind="click: function() { viewModel.items.remove($data); }"> remove </a>
做爲替代,Knockout提供了兩個幫助函數,它們容許您標識與DOM元素關聯的數據: app
ko.dataFor(element)
- 返回可用於與元素綁定的數據 ko.contextFor(element)
- 返回DOM元素可用的整個綁定上下文這些幫助函數能夠在事件處理程序中使用,這些事件處理程序使用相似於jQuery的綁定或單擊的方式地附加。 上面的函數能夠鏈接到每一個連接一個刪除類,如:函數
$(".remove").click(function () { viewModel.items.remove(ko.dataFor(this)); });
更好的是,這種技術能夠用於支持事件委託。 jQuery live / delegate / on函數是一個簡單的方法來實現這一點:this
$(".container").on("click", ".remove", function() { viewModel.items.remove(ko.dataFor(this)); });
如今,單個事件處理程序在更高級別附加,並處理與remove類的任何連接的點擊。 此方法還具備自動處理動態添加到文檔的附加連接(多是因爲項目添加到observableArray的結果)的額外好處。spa
此示例顯示父級和子級的多個級別上的「add」和「remove」連接,每一個類型的連接具備單個處理程序。code
UI源碼:htm
<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>
視圖模型源碼:blog
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; });
不管嵌套連接如何嵌套,處理程序老是可以識別和操做適當的數據。 使用這種技術,咱們能夠避免將處理程序附加到每一個連接的開銷,並能夠保持標記清潔和簡潔。事件