在Knockout2.0之前,计算属性被称之为依赖属性,在2.0版本中,ko.dependentObservable重命名为ko.computed,因为它在读、解释和类型上更简单。在实际使用中,ko.dependentObservable和ko.computed是等价的。
如果有两个监控属性firstName和lastName,想显示全名,就可以使用计算属性,这个方法依赖于一个或多个监控属性,如果任何依赖对象发生改变,他们就会跟着改变。
var myViewModel = { firstName:ko.observable('lady'), lastName:ko.observable('Gaga') };
添加一个计算属性来返回全名
myViewModel.fullName = ko.computed(function(){ return this.firstName() + " " + this.lastName(); },myViewModel);
并且绑定到View视图界面上的元素
The fullname is <span data-bind="text: fullName"></span>
不管是firstName还是lastName改变,全名fullName都会自动更新
效果图:
可写的计算属性
计算属性是通过计算其他监控属性而得到的一个值。所以,计算属性一般都是只读的。实际上只需要提供一个回调函数就能实现写入功能,然后可以把这个可写的计算属性当成一个普通的监控属性来使用,通过自定义的逻辑来实现它的读和写。
var myViewModel = { firstName:ko.observable('lady'), lastName:ko.observable('Gaga') };
对fullName的计算属性进行调整
myViewModel.fullName = ko.computed({ read:function(){ return this.firstName() + " " + this.lastName(); }, write:function(value){ var lastSpacePos = value.lastIndexOf(" "); if(lastSpacePos>0){ this.firstName(value.substring(0,lastSpacePos)); this.lastName(value.substring(lastSpacePos + 1)); } }, owner:myViewModel });
♦ read(必选):一个用来执行取得依赖监控属性当前值的函数
♦ write(可选):如果声明将是你的依赖属性可写
♦ owner(可选):如果声明,它就是KO调用read或write的回调函数时用到的this
在这个例子上,write回调事件来处理用户输入的值将其分解成“firstName”和“lastName”两个部分,并将这些值返回到底层监控属性上。可以将view model绑定到DOM元素上。
<p>First name:<span data-bind="text:firstName"></span></p> <p>Last name: <span data-bind="text: lastName"></span></p> <p>Full name: <input data-bind="value: fullName"/></p>
效果图:
验证用户输入
在上面的ViewModel中添加两个个属性
var myViewModel = { firstName:ko.observable('lady'), lastName:ko.observable('Gaga'), age:ko.observable(30), ageWasValid:ko.observable(true) };
添加一个计算属性
myViewModel.ageValue = ko.computed({ read:myViewModel.age, write:function(value){ if(isNaN(value)){ this.ageWasValid(false); }else{ this.ageWasValid(true); this.age(value); } }, owner:myViewModel });
进行绑定View视图界面元素
<p>Enter a age:<input data-bind="value: ageValue"/></p> <font data-bind="visible: !ageWasValid()" color="red">That's not a number!</font>
效果图:
依赖跟踪的原理
1.声明一个依赖属性时,KO会立即调用求值算法得到其初始值;
2.计算函数运行的时候,KO会把监控属性通过计算得到的值都记录在一个Log中;
3.计算结束的时候,KO会订阅能够访问的监控属性或依赖属性,订阅的回调函数是重新运行计算函数,循环整个过程,回到步骤1(并且注销不再使用的订阅);
4.KO会通知所有的订阅者,依赖属性已经被设置了新值。
所以说,KO并不仅仅是在第一次执行计算函数时检测你的依赖项,它每次都会检测。这意味着,你的依赖是可以动态的,你不需要定义依赖关系:在代码运行时会自动检测到。