所谓绑定上下文就是当前绑定(dat-bind)所使用到的对象(ViewModel)。在单个对象绑定的情况下是很容易理解的,但对象可能是复杂的类型,嵌套很多层,这个时候每层都有自己的上下文对象,理解起来就不是很方便了。ko通过上下文关键字,让层次间的关系变得更加清晰,相互访问变得更加简单。
一、$data 与 $index
上一篇介绍了ObservableArray和template,通常我们通过对象属性进行绑定,例如:data-bind="text:属性名称";但如果数组只是简单格式呢,例如["tom","jack","lucy"],这个时候可以用ko的几个上下文来实现。
$data 表示当前对象。下面的$data就表示 person对象。
<p>姓名:<span data-bind="text:$data.name"></span>,年龄:<span data-bind="text:$data.age"></span></p>
function Person(name,age){
this.name = name;
this.age = age;
}
var person = new Person("tom",18);
ko.applyBindings(person);
而对于["tom","jack","lucy"] 数组,$data 就是每个项的值。
$index 表示当前下标。例子:
<ul data-bind="foreach:arr">
<li><span data-bind="text:$index"></span>:<span data-bind="text:$data"></span></li>
</ul>
var arr = ["tom","jack","lucy"];
ko.applyBindings(arr);
二、$parent、$parents、$root
$parent 表示父ViewModel。例如:
<ul data-bind="foreach:data">
<li>
<p data-bind="text:name"></p>
<ul data-bind="foreach:contains">
<li>
<p><span data-bind="text:name"></span>属于<span data-bind="text:$parent.name"></span></p>
</li>
</ul>
</li>
</ul>
var data = [
{name:"水果",contains:[{name:"苹果",work:"苹果的作用"},{name:"香蕉",work:"香蕉的作用"}]},
{name:"蔬菜",contains:[{name:"青菜",work:"青菜的作用"},{name:"白菜",word:"白菜的作用"}]}
];
内部的 ul 的ViewModel是 contains 对象,之前我们用as 指定别名来访问data[i]的name属性,这里也可以直接通过$parent.name访问上层的ViewModel的name属性。
$parents 表示所有父ViewModel集合。这是一个数组,$parents[0] 就是父ViewModel,也就是 $parent;$parenrs[1] 就是父的父ViewModel...。
$root 表示根ViewModel。上面的例子,$parent 和 $root 是一样的,都表示 data 对象。如第一个例子,如果此时是在根部的话,那么 $root 与 $data 就是一样的。
三、$parentContext
表示上层的具体数据。$parent表示父ViewModel,$parentContext.$data 就可以访问这个ViewModel。如果要获得父 $index,则必须通过$parentContext.$index。
四、with 关键字
指定当前上下文,例如:
<div data-bind="with:info">
<p data-bind="text:name"></p>
<p data-bind="text:age"></p>
</div>
这样就不用老是写 info.name,info.age 了,在数据复杂时,可以简写代码。
五、总结
以上就是ko上下文几个常用的关键字,$data, $index, $parent, $root 在复杂数据类型时特别有用; with 关键字在属性多的时候可以简写代码,通过指明当前上下文,让语义更加清晰,阅读起来更加方便。