Dynamic composition using knockout and durandal doesn't work

北战南征 提交于 2020-01-16 00:40:26

问题


I have a strange problem while using Durandal/Knockout. In some cases the binding doesn't work properly. I've simplified my situation which came in this question.

I'm setting composition info somewhere in my code like:

compositionInfo({
    model: viewModelInstance,
    view: viewName,
    activate: viewModelInstance.activate
    });

And this is my view:

<div id="service-container" 
    data-bind="compose: { model: compositionInfo().model,
                          view: compositionInfo().view, 
                          activate: compositionInfo().activate}">

At the first time, the composition works fine. But on the next time when the compositionInfo changes (using the same lines and in the same place of the code), nothing happens.

The first time there is a ["Activating",...] in the log window. But in the second time there's no such log or ["Binding"] log.

I've traced the Durandal and Knockout code and find out that in the knockout-2.3.0.debug file there's a evaluateImmediate() function which runs this line on first time (correct ones):

var newValue = readFunction.call(evaluatorFunctionTarget);

and causes the composition to start to activating the model.

But when it's not working in the evaulateImmediate() it returns some lines above by this code:

// Don't dispose on first evaluation, because the "disposeWhen" callback might
// e.g., dispose when the associated DOM element isn't in the doc, and it's not
// going to be in the doc until *after* the first evaluation
if (_hasBeenEvaluated && disposeWhen()) {
    dispose();
    return;
}

What is this code for? Everything works fine if I comment these lines.

This problem varies computer to computer. On my computer in most cases it just work the first time. but on other computer it works most of the time and fails about 3/10 cases.

FYI I'm using Durandal 1.1.1 and Knockout 2.3.0


回答1:


I see a problem in your compositioninfo observable. The value of activate should be true or false and the viewModelInstance.activate function itself will be found/called by composition binding.

Here is a link to the relevant doc - https://github.com/BlueSpire/Durandal/blob/master/docs/1.2/Composition.html.md#activate

Is this just typo/problem with you trying to create a simplified version of your code?

compositionInfo({
    model: viewModelInstance,
    view: viewName,
    activate: true
});



回答2:


As I mentioned in the question, using durandal 1.2 the only way to have proper binding is to commend these lines:

// Don't dispose on first evaluation, because the "disposeWhen" callback might
// e.g., dispose when the associated DOM element isn't in the doc, and it's not
// going to be in the doc until *after* the first evaluation
if (_hasBeenEvaluated && disposeWhen()) {
    dispose();
    return;
}

But after upgrading to Durandal 2.0.1, these commented lines causes some activations to happen more than once.

So keep in mind if you upgrade to 2.0.1 uncomment these lines or just get the original knockout code.



来源:https://stackoverflow.com/questions/19751104/dynamic-composition-using-knockout-and-durandal-doesnt-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!