Knockout.js 防止收集依赖项

Knockout.js 防止收集依赖项,knockout.js,computed-observable,Knockout.js,Computed Observable,是否有一个好方法大致实现以下概念: var computed = ko.computed(function() { readSomeObservables(); //<-- if these change, notify computed ko.stopCollectingDependencies(); readSomeMoreObservables(); //<-- if these change, do not notify computed ko

是否有一个好方法大致实现以下概念:

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

但由于明显的原因,这很难达到理想状态,在某些情况下会导致不希望的行为。

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


敲除的依赖项检测有一个
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);
});

组合怎么样。为需要读取但不想订阅的订阅文件创建一个临时计算值。更改它们将更新计算的温度,但这可能是一个廉价的操作。您的real computed通过peek访问当前缓存的值读取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(); 
});
//此项已更新
//如果readSomeMoreObservables中使用的任何子项发生更改
//但这很便宜
var tempComputed=ko.computed(函数(){
readSomeMoreObservables();
});
var computed=ko.computed(函数(){

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

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
});
var computed=ko.computed(函数(){
var a=readSomeObservables();//供以后的访问者使用

版本3.3公开了ko.ignoreDependencies(回调、回调目标、回调参数)。这是绑定处理程序在内部使用的方法,用于避免从init函数调用创建依赖项


请参见

如果不希望在这些更改时更新,为什么要从计算中读取它们?我将重申问题中所说的:情况相当复杂,外部模块可以提供额外的回调,需要在执行流中的特定点调用,但如果这些回调恰好涉及读取从可观测值来看,这些可观测值不应参与计算。因此,我可以重新设计整个模块(昂贵)或找到解决方法(便宜)。因此,当这些更改发生时,计算机不需要向其订阅方发布?正确吗?@Anders close-计算机首先不应该订阅这些观察值;因为它不能重新评估自己的读取功能,更不用说通知其订阅方。你不能让readSomeMoreObservables背后的团队将其扩展到我们两人e peek还是标准读取?我的小提琴在observable two try最新版本的更新中出现了一个错误。这并没有解决问题,因为我无法控制真实场景中的所有代码。ko不支持这种开箱即用的功能,您确实需要使用peek,因为您无法更改函数readSomeMoreObservables,这将很难。ko.dependencyDetection是一个内部帮助函数哦,我错过了这个函数。你可以创建你自己的敲除构建,导出属性:ko.exportSymbol('dependencyDetection',ko.dependencyDetection);好主意,我用提琴测试了我的答案,Oops,在我完全了解此解决方案的含义之前发布了一条评论。这是一个非常好的主意-我添加了
延迟评估
,以确保调用顺序保持不变:谢谢!这是一个好主意,但对于以后的访问者,@RockResolve提供了一个更现代的解决方案。有什么建议与
.peek()
function?OP peek()相比,它的优势在于peek()只忽略了最初的可观察值,而ignoreDependencies在回调周围创建了一个新的作用域。
// 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(); 
});
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
});