问题
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