*本文已經同步至索引目錄:http://www.cnblogs.com/wbpmrck/archive/2012/05/16/Knockout-introduction.html
前言&基礎
最近連續幾個禮拜加班,實在是沒有心情寫博客。今天終於可以休息一下,繼續我們的Knockout之旅。
上一篇文章,我們感受了一下control flow的威力,那就是利用viewModel綁定列表元素到DOM上,在這個過程中,由於綁定的數據出現了嵌套,我們使用了一些關鍵字來實現訪問不同的層次對象:
- $parent:訪問當前綁定對象的上一層次對象
- $data:訪問當前綁定對象自身
這些關鍵字所指向的對象,是基於當前的綁定對象的層次來計算的,當一個綁定發生的時候,ko內部會生成一個Binding Context(綁定上下文),也就是我們今天主要了解的東東,總體來說Binding Context的規則是這樣的:
- 使用ko.applyBindings方法后,當前綁定上下文就是ViewModel本身(此時你可以直接綁定里面的屬性到DOM中)
- 使用control flow綁定,會修改當前的綁定上下文到你綁定的對象
下面我們就通過分析一個例子,來了解Binding Context
正文
了解Binding Context概念
我們先來看一段代碼,是在前面一章中出現過的:
var ViewModel=function() { var self = this; self.people = ko.observableArray([ { name: 'Bert' }, { name: 'Charles' }, { name: 'Denise' } ]);//people是一個監控數組 self.removePerson = function() { self.people.remove(this); };//removePerson是一個定義在ViewModel下的方法 };
這個ViewModel構造函數我把他簡化了一下,主要看一下定義的這2個屬性:
- people:一個監控數組,存放了我們初始化的3個對象,每個對象都只有一個name屬性,存放一個名詞
- removePersion:一個function,用來從people數組中刪除一個記錄,注意這里傳入的參數是this
然后我們看一下Html中如何綁定這個viewmodel:
<ul data-bind="foreach: people"> <li> Name: <span data-bind="text: name"> </span> <a href="#" data-bind="click: $parent.removePerson">Remove</a> </li> </ul>
這里我同樣把代碼簡化了一下,我們只關注這一個foreach綁定:
- 首先在ul上,我們使用foreach綁定到viewModel中的people屬性(記住他是一個監控數組哦)
- 接着在下面的li中,我們隊第一個span元素使用text綁定,對象是name屬性。
- 再下面的a標簽,我們使用click綁定,我們希望這個綁定可以調用viewModel中的removePerson方法
現在我們看Html中是如何實現這些功能的,從中我們可以體會一下Binding Context的存在:
首先看一下現在的對象層次結構

- 首先看foreach綁定,直接指向people這個屬性,是因為我們當前的Binding Context是ViewModel自身:

- 接下了由於我們使用了foreach,KO發現你要綁定的是一個數組,就將當前Binding Context指向這個數組

- 再接下來我們要綁定數組中的一個對象的name屬性到span上,由於當前的綁定上下文已經是數組了,所以我們可以直接使用數組元素的name屬性來完成綁定
到這里,我們發現Binding Context隨着Control Flow的使用,一層層向下延展開來,這樣有一個好處,就是方便我們進行更細層次的綁定,語法更加簡單。因為上下文已經隨着foreach的指定而變化,我們只需要關注當前上下文內的哪些屬性使我們需要的。
訪問上層Context
這里我們先考慮一下,如果需要從數組中刪除一個記錄,那么我們需要調用ViewModel下面的removePerson方法。如果直接使用click綁定到removePerson,行不行呢?從上面我們的分析得知,當前我們的上下文已經轉移到了people數組內部,這里面是沒有removePerson的方法定義的。(感興趣的朋友可以自己嘗試一下,直接綁定到removePerson,看ko是否報錯)。
所以KO為我們提供了一系列的特殊語法,幫助我們“跳出”當前的上下文,去訪問其他層次的對象,比如:
- $parent:訪問當前上下文的父元素
好了,這下就明白了為什么需要用“data-bind="click: $parent.removePerson"”這樣的方式來綁定removePerson方法了
綁定對象&綁定函數的調用對象
細心的朋友應該會發現, 在removePerson函數里,我們從people數組中刪除一個元素,使用的參數是this.其實這個this指向的是people的一個元素,也就是{name:'xxx'}對象。當我們通過$parent方法訪問到ViewModel這個對象的removePerson方法時,KO內部其實為這個方法的調用指定了一個調用對象(對函數的調用對象概念不清楚的,可以看一下javascript基礎),而這個調用對象就是當前綁定到的對象,我這里給他起個名字,叫做“綁定對象”:
- $data:指向當前Binding到的對象引用,他是Binding Context下的直接屬性
在Html中,我們也可以通過$data直接訪問當前的綁定對象,在本例中,$data就是指{name:'xxx'}對象.由於KO直接幫我們綁定到的方法:removePerson指定了調用對象,所以我們直接在該方法中使用this關鍵字就可以訪問到$data啦~
其他的上下文訪問關鍵字
除了$data和$parent以外,KO還提供了很多關鍵字來訪問不同的上下文:
- $parents:一個數組,通過0開始的下標依次訪問上一層的上下文:$parents[0]就是$parent,$parent[1]是$parent的$parent,依次類推
- $root:指向ViewModel,也就是綁定上下文的根
總結
今天主要介紹了ko中的綁定上下文,這個概念對於我們在比較復雜的頁面中使用各種綁定非常有用,大家要好好理解哦~
感謝支持
如果本文對您有幫助的話,請別吝嗇手中的推薦票哦~
