1

Say you have a view model with a circular dependency. I know you should avoid this in normal circumstances, but for this case assume you can't because it's out your control. A parent and a child refer to each other. Below is for brevity a very simplified example:

Html:

<div id="root">
    <div data-bind="text: parent.childName()"></div>
</div>

JS:

var page = {};

page.parent = 
{ 
    name: ko.observable('parent'), 
    childName: ko.computed(function() { return page.child.name(); })
};
page.child = 
{ 
    name: ko.observable('child'), 
    parentName: ko.computed(function() { return page.parent.name(); })
};

ko.applyBindings(page, document.getElementById('root') );

JS Fiddle

The problem is that ko.computed is executed the first time it is initialized. If it would only execute at the moment of applyBindings everything would be perfectly fine.

One solution would be to remove ko.computed altogether and just use a plain normal function. Those are only executed at the moment of applyBindings. Problem is of course that you lose all the other advantages of ko.computed, like losing the caching functionality etc.

Is there a way to say that a computed observable only starts initializing at the applyBindings phase?

4

2 回答 2

4

使用deferEvaluation选项将计算的评估推迟到首次访问时:

ko.computed({
    read: function() { return page.parent.name(); },
    deferEvaluation: true
});

JSFiddle

于 2014-11-28T14:14:39.033 回答
1

另一种解决方案:

childName: ko.computed(function() { return page.child && page.child.name(); }).

undefined如果 child 未设置,它将返回;

于 2014-11-28T14:27:38.707 回答