我已经有一段时间了解这个并没有找到解决方案,希望你能提供帮助。
在我使用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代码本身。这是淘汰赛中的一个错误吗?什么是建议的解决方案/解决方法?
谢谢!
答案 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?