Prevent calculation from dependency collection

Is there a good way to approach the following concept:

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

I know peek(), but in this case, the computed method calls the methods that were provided from the external module, and the design requires that it be purely random if these methods are related to observables.

I have one solution that should roughly do this:

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

But for obvious reasons, this is hardly ideal and leads to unwanted behavior in some situations.

+5
source share
5 answers

. temp, , , . , . tempComputed .

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

...

3.3 ko.ignoreDependencies(callback, callbackTarget, callbackArgs). , , init.

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

+5

, , , :

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. , . , .

+2

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);
});
+1

, ?

http://jsfiddle.net/uUXWv/2

var observableTwoInitialState = this.observableTwo(); 

this.computed = ko.computed(function() {
    return this.observableOne() + observableTwoInitialState;
}, this);
0
source

All Articles