使用计算属性上(Computed Observable)

计算属性 Computed Observable

如果你已经有了一个监控属性firstName和lastName,如果你想显示全名该怎么做呢?这个时候你就可以通过计算属性来实现,这个方法依赖于一个或多个监控属性,如果任何依赖对象发生改变他们就会跟着改变。

例如,下面的 view model:

function AppViewModel(){
 this.firstName=ko.observable('Bob');
 this.lastName=ko.observable('Smith');
}

你可以添加一个计算属性来返回全名,例如:

function AppViewModel(){
 // ... leave firstName and lastName unchanged ... 
this.fullName=ko.computed(function(){
   return this.firstName()+" "+this.lastName();
 },this);}

下面你就可以将它绑定到UI对象上了,如:

Thenameis<span data-bind="text: fullName"></span>

当firstName或者lastName变化,它将会随时更新(当依赖关系发生变化,你的计算函数就会被调用,并且它的值都会更新到UI对象或其他的依赖属性上去)。

管理"this"

初学者不妨可以调过这一节—只要你遵循示例规范你的编码模式,你不需要关系它。

你可能想知道ko.computed的第二个参数是什么(前面的代码中我们使用到了this),当依赖属性时定义了this的值,没有传递它进去,你不可能得到this.firstName()或者this.lastName().有经验的JavaScript开发人员觉得this没什么的,但如果你不熟悉JavaScript,你就会觉得这样写很奇怪。(像C#和Java这类语言不需要开发人员给this赋值,但JavaScript需要,因为在默认情况下,它的函数本身并不是任何对象的一部分)。

一种简化的流行惯例

当你需要全程跟踪this时,下面的写法是一种很流行的惯例:如果你将你的 viewmodel's结构this作为一个变量复制一份(传统称之为self),在以后你可以使用self来代表viewmodel而不必担心它重定义或指别的东西。例如:

function AppViewModel(){
 var self=this;
 self.firstName=ko.observable('Bob');
 self.lastName=ko.observable('Smith');
 self.fullName=ko.computed(function(){
 return self.firstName()+" "+self.lastName();
 });
}

由于self在闭合的方法内部也是可以捕获到的,所以在任何任何嵌套函数当中,它仍然可用并保持一致性。 如ko.computed求值,当涉及到事件处理时它依然显得很有用。你可以通过在线实例了解更多。

依赖链工作

当然,如果你愿意,你可以创建一个完整的依赖属性链。例如,你可能有:

1、用items监控属性来代表一组items项

2、另外一个selectedIndexes监控属性来用户已选择项目的索引

3、一个selectedItems依赖属性来返回一组用户已选择的Item对象

4、另外一个依赖属性来返回true或者false,来表示selectedItems中是否包含一些属性(如新的或尚未保存的)。一些UI元素,比如一个按钮可以基于此值来控制其启用或禁止。

然后,当改变items或者selectedIndexes都会影响到所有的依赖属性链,然后依次更新到绑定了这些项的UI。非常的整洁和优雅。