Computed Observables

Computed Observables

参考:http://knockoutjs.com/documentation/computedObservables.html

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

然后在ui中可以使用

The name is <span data-bind="text: fullName"></span>

这里传入了this,如果没有传入this就无法调用firstName,lastName
使用self可以简化

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();
    });
}

如果computed只是计算并返回依赖observable的值,最好使用 ko.pureComputed

this.fullName = ko.pureComputed(function() {
    return this.firstName() + " " + this.lastName();
}, this);

这样它们的更新不会去通知其他的对象(3.2.0中加入)
设置为alwasy通知

myViewModel.fullName = ko.pureComputed(function() {
    return myViewModel.firstName() + " " + myViewModel.lastName();
}).extend({ notify: 'always' });

延迟通知

// Ensure updates no more than once per 50-millisecond period
myViewModel.fullName.extend({ rateLimit: 50 });

检测是否是一个computed observable
有时候需要把computed observable的内容刨除,比如例子中把非computed observable的内容返回并存储到数据库中

for (var prop in myObject) {
    if (myObject.hasOwnProperty(prop) && !ko.isComputed(myObject[prop])) {
        result[prop] = myObject[prop];
    }
}

其他

ko.isObservable            如果是observables、 observable arrays、computed observables返回true
ko.isWritableObservable    如果是observables, observable arrays, and writable computed observables返回true

如果只是想在ui中使用,可以声明为函数

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

在ui中这样使用

The name is <span data-bind="text: fullName()"></span>

Writable computed observables

http://knockoutjs.com/documentation/computed-writable.html

依赖跟踪

http://knockoutjs.com/documentation/computed-dependency-tracking.html

Pure computed observables

根据是否具有变化的订阅者,自动转换

this.fullName = ko.pureComputed(function() {
    return this.firstName() + " " + this.lastName();
}, this);

也可以这样

this.fullName = ko.computed(function() {
    return this.firstName() + " " + this.lastName();
}, this, { pure: true });
<div class="log" data-bind="text: computedLog"></div>
<!--ko if: step() == 0-->
    <p>First name: <input data-bind="textInput: firstName" /></p>
<!--/ko-->
<!--ko if: step() == 1-->
    <p>Last name: <input data-bind="textInput: lastName" /></p>
<!--/ko-->
<!--ko if: step() == 2-->
    <div>Prefix: <select data-bind="value: prefix, options: ['Mr.', 'Ms.','Mrs.','Dr.']"></select></div>
    <h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
<!--/ko-->
<p><button type="button" data-bind="click: next">Next</button></p>
function AppData() {
    this.firstName = ko.observable('John');
    this.lastName = ko.observable('Burns');
    this.prefix = ko.observable('Dr.');
    this.computedLog = ko.observable('Log: ');
    this.fullName = ko.pureComputed(function () {
        var value = this.prefix() + " " + this.firstName() + " " + this.lastName();
        // Normally, you should avoid writing to observables within a pure computed 
        // observable (avoiding side effects). But this example is meant to demonstrate 
        // its internal workings, and writing a log is a good way to do so.
        this.computedLog(this.computedLog.peek() + value + '; ');
        return value;
    }, this);
 
    this.step = ko.observable(0);
    this.next = function () {
        this.step(this.step() === 2 ? 0 : this.step()+1);
    };
};
ko.applyBindings(new AppData());

Observable Reference

构造computed observable
形式1:ko.computed( evaluator [, targetObject, options] )

evaluator       计算值的函数
targetObject    this
options         额外属性

形式2:ko.computed( options )
可以接受一个js对象,可接收如下参数

read            必选
write
owner
pure
deferEvaluation
disposeWhen
disposeWhenNodeIsRemoved

形式3:ko.pureComputed( evaluator [, targetObject] )
形式4:ko.pureComputed( options )

使用

dispose()
extend(extenders)
getDependenciesCount()
getSubscriptionsCount( [event] )
isActive()
peek()
subscribe( callback [,callbackTarget, event] )

确定observable类型

ko.isObservable
ko.isWritableObservable
ko.isComputed
ko.isPureComputed

使用computed context
可以访问ko.computedContext,获取信息

isInitial() 
getDependenciesCount() 

比如

var myComputed = ko.computed(function() {
    // ... Omitted: read some data that might be observable ...
 
    // Now let's inspect ko.computedContext
    var isFirstEvaluation = ko.computedContext.isInitial(),
        dependencyCount = ko.computedContext.getDependenciesCount(),
    console.log("Evaluating " + (isFirstEvaluation ? "for the first time" : "again"));
    console.log("By now, this computed has " + dependencyCount + " dependencies");
 
    // ... Omitted: return the result ...
});
posted @ 2017-03-15 15:58  zhangshihai1232  阅读(145)  评论(0)    收藏  举报