Knockout Subscription

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 Subscribable
function PubSub() {
    // inherit Subscribable
    ko.subscribable.call(this);
}

// create an instance of our Subscribable
var pubsub = new PubSub();
// make a subscription
var 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 things
subscription1.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 factory

ko.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的机制中,极大地丰富了对事件的处理功能,典型的观察者模式的运用,值得深入了解其原理。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值