Knockout Subscription

来源:互联网 发布:台湾淘宝跟大陆一样吗 编辑:程序博客网 时间:2024/06/08 04:53

Knockout中使用订阅(subscription)的方式来处理DOM元素的值改变的事件(当然修改数据源中的相应值也会触发)。在开发过程中,往往需要做DOM元素的联动效果,以往都是自己捕获DOM的change事件,现在有了Knockout的订阅特性,我们就只需要将我们的关注点放在对订阅的回调事件的处理逻辑上。

1.简单使用

在定义ViewModel的时候,指明ViewModel的属性subscribe的回调函数即可!

var Person = function() {    var self = this;    self.name = ko.observable("justin");    self.name.subscribe(function(newValue) {         alert("The person's new name is " + newValue);    });};var person = new Person();//person.name("justin");ko.applyBindings(person);
回调函数会传入一个参数,这个参数可以是简单对象,也可以是复杂对象。当数据源的值改变时(如person.name("justin")这句执行时,或者DOM上修改knockout所绑定元素的值的时候),这个subscribe方法就会自动执行。

<div style="margin-left: 10px;margin-top: 10px">   <input type="text" data-bind="value:name" /></div>
这里我们绑定了一个input元素的值到Person对象的name属性,当name值发生改变时就会触发subscribe。


我们的默认值是justin,值修改之后,立即触发事件。如果我们需要与其他控件进行联动,这样做就很方便了。

2.多事件订阅

一个对象的某个属性其实可以订阅多个事件。

var test = ko.observable();// create a subscription for the "test-event"test.subscribe(function (val) {     console.log(val);}, test, "test-event1");test.subscribe(function (val) {     for (var i in val) {        console.log(val[i]);     }     //console.log(val[0]);     //console.log(val[1]);}, test, "test-event2");test.notifySubscribers("Hello World1", "test-event1");test.notifySubscribers(["Hello","World"],"test-event2");
这里我们的一个属性订阅了两个事件,test-event1和test-event2,我们调用test.notifySubscribers方法来通知所有的订阅者,事件被调用了!

这里我们可以把test-event1和test-event2理解为订阅的主题(topic),我们针对不同的主题设定不同的回调事件!

下面的例子更为贴切:

// Dummy Subscribablefunction PubSub() {    // inherit Subscribable    ko.subscribable.call(this);}// create an instance of our Subscribablevar pubsub = new PubSub();// make a subscriptionvar subscription1 = pubsub.subscribe(function (val) {     console.log(val);}, pubsub, 'test-topic1');var subscription2 = pubsub.subscribe(function (val) {    console.log(val);}, pubsub, 'test-topic2');pubsub.notifySubscribers("hello topic1", "test-topic1");pubsub.notifySubscribers("hello topic2", "test-topic2");// console: "hello world"// clean up thingssubscription1.dispose();subscription2.dispose();
这里需要脑补一点javascript的call方法:
call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象。 说明: call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。 
其实PubSub可以理解为在ko.subscribe上封装了一层,代码subscribable对象去调用subscribe方法而已!

Obserable对象是knockout的核心,其简单实现如下:

// Very Simple Knockout Observable Implementation// ko.observable is actually a function factoryko.observable = function (initialValue) {    // private variable to hold the Observable's value    var _latestValue = initialValue;    // the actual "Observable" function    function observable() {        // one or more args, so it's a Write        if (arguments.length > 0) {            // set the private variable            _latestValue = arguments[0];            // tell any subscribers that things have changed            observable["notifySubscribers"](_latestValue);            return this; // Permits chained assignments        }        else { // no args, so it's a Read            // just hand back the private variable's value            return _latestValue;        }    }    // inherit from Subscribable    ko.subscribable.call(observable);

3.总结

knockout将发布订阅引入到MVVM的机制中,极大地丰富了对事件的处理功能,典型的观察者模式的运用,值得深入了解其原理。






0 0
原创粉丝点击