observable 函数声明的变量两个特征:
-
被声明的变量返回是一个函数
-
实现knockoutjs 双向绑定的关键,是 view 和 viewmodel 双向绑定的桥梁
ps:observable 变量的读写都是以函数的形式。
observable 变量声明
var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable(123)
};
读 observable
ko.observable 对象都是函数。所以读取对象的值是如下这种方式
myViewModel.personName();
//'Bob'
写 observable
函数传参的形式
myViewModel.personName('Mary');
支持链式方式来修改observable 对象
链式写法可以同时修改多个observable 对象
myViewModel.personName('Mary').personAge(50)
订阅observable 对象的消息
有这样的场景,需要知道某个 observable 变量什么时候发生变化,并且做一些操作。这时候就用到 subscribe 函数了。
myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
上面的代码表示当 personName 的值发生改变的时候,就出发一个回调函数。
subscribe 函数是knockoutjs 内部工作原理。只有这个消息机制,knockoutjs 才能什么时候进行双向绑定的更新操作。
subscribe 的参数
-
callback 回调函数是当有消息返回是触发
-
target 定义 callback 函数中的 this
-
event 触发通知的事件类型,默认是 change 。 beforeChange change
订阅是可以终止的。第一次订阅会返回一个变量,然后调用 dispose 函数。如下
var subscription = myViewModel.personName.subscribe(function(newValue) { /* do stuff */ });
// ...then later...
subscription.dispose(); // I no longer want notifications
是不是看着很熟悉,这种形式和dom 事件的侦听和取消侦听一样的。 dispose 函数是用了释放ko对象用的。
如果需要在对象变化前获取事件,可以像下面这样
myViewModel.personName.subscribe(function(oldValue) {
alert("The person's previous name is " + oldValue);
}, null, "beforeChange");
强制 observable 对象每次都触发通知
正常情况下,只有放observable 变量的值真实发生变化时(新老值不一样)才触发通知。如果加上 extend({ notify: ‘always’ }) 扩展,那么只要修改 observable 对象就触发通知,不管它的值是否发生变化。
myViewModel.personName.extend({ notify: 'always' });
延迟或者抑制 change 通知
正常情况下,只要 observable 发生变化,会立即发出通知。但是如果一个 observable 持续发火说呢过变化,那么就会一直发出通知,这样大量的通知可能会触发性能问题。典型的应用场景是 input 输入框的联想查询,当用户输入间隔300 ms时触发查询,不然会产生大量的ajax 请求。
// Ensure it notifies about changes no more than once per 50-millisecond period
myViewModel.personName.extend({ rateLimit: 50 });
那么像这样做就ok了。