使用构造的Knockout强制更新整个html

时间:2013-06-01 16:53:18

标签: knockout.js durandal

我已经有一段时间了解这个并没有找到解决方案,希望你能提供帮助。

在我使用Knockout和durandal构建的SPA应用程序中,我非常依赖于knockoutJS的With构造。通过矿山和durandals架构的核心深深嵌入的东西。

许多操作都带有相关路由,以便将以前的操作存储在浏览器历史记录中。现在一个动作也可能操纵DOM或触发CSS转换(例如在内部div上设置一个开始转换的类)。

不幸的是,每次重新评估with binding时,都会重建使用该语句的整个DOM,从而撤消我的DOM更改并终止转换。这正是我的场景中发生的事情,类似于以下伪:

<div data-bind="with: myViewModel">
    ... print current datetime ....
</div>
...
myViewModel(myViewModel());

请参阅此jsfiddle以获取此行为的更具体示例:http://jsfiddle.net/k32Xf/

这个问题只适用于with构造但是我没有找到解决方法,除了通过黑客攻击durandal代码本身。这是淘汰赛中的一个错误吗?什么是建议的解决方案/解决方法?

谢谢!

1 个答案:

答案 0 :(得分:1)

如果您的myViewModel观察发生了变化,那么with内的所有内容都将被重建。这只是让它发挥作用的唯一方法。

但是,在您的示例jsFiddle中,您实际上并未更改observable的值。您只是再次分配相同的视图模型。不幸的是,这会触发更新,即使您可能不希望这样做。

默认情况下,Knockout observable将新值与先前值进行比较,以确定它是否不同并应触发更新。它使用equalityComparer来完成此操作。默认实现将考虑不同的对象,即使它是同一个实例。

因此,您可以通过提供使用引用相等性的自定义equalityComparer来解决您的问题。这很简单:

myViewModel.equalityComparer = function (a, b) { return a === b; };

以下是jsFiddle的修改版本,在实践中显示了这一点:http://jsfiddle.net/CFhkT/1/

以下是有关他们为何选择以对象方式实现相等性的更多信息:Why does Knockout.js's default equality comparer treat non-primitive types as not equal?