5

有没有好办法大致实现如下概念:

var computed = ko.computed(function() {
    readSomeObservables(); //<-- if these change, notify computed
    ko.stopCollectingDependencies();
    readSomeMoreObservables(); //<-- if these change, do not notify computed
    ko.resumeCollectingDependencies();
});

我知道peek(),但在这种情况下,计算调用的是从外部模块提供的方法,并且如果这些方法碰巧涉及可观察对象,则设计要求它纯粹是偶然的。

我有一个解决方案,大致是这样做的:

window.setTimeout(function() {
    readSomeMoreObservables();
}, 0);

但由于显而易见的原因,这并不理想,并且在某些情况下会导致不良行为。

4

5 回答 5

6

对于以后的访客...

3.3 版公开了 ko.ignoreDependencies(callback, callbackTarget, callbackArgs)。这是绑定处理程序处理在内部使用的方法,以避免从 init 函数调用创建依赖关系。

http://www.knockmeout.net/2015/02/knockout-3-3-released.html

于 2015-08-04T03:25:39.257 回答
4

怎么组合。为您需要阅读但不想订阅的可订阅内容创建一个临时计算。更改它们会更新计算的温度,但这可能是一个便宜的操作。您的实际计算读取 tempComputed 并 peek 访问当前缓存的值。

// this one is updated 
// if any of the subscribeables used in readSomeMoreObservables changes
// but that is hopefully cheap
var tempComputed = ko.computed(function() {
    readSomeMoreObservables();
});


var computed = ko.computed(function() {
    readSomeObservables(); //<-- if these change, notify computed

    // do not update on readSomeMoreObservables
    tempComputed.peek(); 
});
于 2013-01-30T14:30:53.510 回答
2

我有点晚了,但这是我在这种情况下使用的解决方案:

var computed = ko.computed(function() {
    var a = readSomeObservables(); //<-- if these change, notify computed
    var b;

    // capture any dependencies from readSomeMoreObservables
    // in a temporary computed, then immediately dispose
    // of it to release those captured dependencies
    ko.computed(function() { b = readSomeMoreObservables(); }).dispose();

    return a + b; // or whatever
});

这会创建一个临时计算对象,我们在其中调用readSomeMoreObservables. 临时计算设置了一个新的依赖捕获帧,因此所有读取的 observables 都被捕获到我们的临时计算中。然后我们立即处理临时计算以释放它捕获的任何依赖项。

于 2013-03-13T04:36:53.083 回答
1

Knockout 的依赖检测有一个ko.dependencyDetection.ignore功能。如果我理解正确,您可以使用它来读取可订阅的值,而无需创建对它们的依赖。

至少运行以下测试:

it('Should not subscribe to subscribeables called by ignore', function() {


    var observableInner = ko.observable('initial'),
        observableOuter = ko.observable(),
        called = 0,
        computedInner = ko.computed(function() { return observableInner(); }),
        computedOuter = ko.computed(function() { 
            called += 1;
            // read dependend
            observableOuter();

            // read ignored
            var result = ko.dependencyDetection.ignore(computedInner, null)
            expect(result).toEqual('initial');

            return true;
        });

    expect(called).toEqual(1);

    // update the one we are depending on
    observableOuter(1);
    expect(called).toEqual(2);        

    // update the inner one which should trigger an update to computedInner but not to computedOuter
    observableInner('ignore');
    expect(called).toEqual(2);
});
于 2013-01-30T13:31:39.277 回答
0

如果您对这些可观察对象的新值不感兴趣,为什么不将可观察对象的读数移到计算范围之外呢?

http://jsfiddle.net/uUXWv/2

var observableTwoInitialState = this.observableTwo(); 

this.computed = ko.computed(function() {
    return this.observableOne() + observableTwoInitialState;
}, this);
于 2013-01-30T13:08:11.507 回答