0

我已经为此苦苦挣扎了一段时间,还没有找到解决方案,希望您能提供帮助。

在我用 Knockout 和 durandal 构建的 SPA 应用程序中,我严重依赖于 knockoutJS 的 With 构造。在我的和 durandals 架构的核心中深深嵌入的东西。

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

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

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

有关此行为的更具体示例,请参阅此 jsfiddle:http: //jsfiddle.net/k32Xf/

这个问题只存在于 with 构造中,但是除了破解 durandal 代码本身之外,我还没有找到解决方法。这是淘汰赛中的错误吗?建议的解决方案/解决方法是什么?

谢谢!

4

1 回答 1

1

如果您的myViewModel可观察到的变化,那么确实with将重建其中的所有内容。这只是使它工作的唯一方法。

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

默认情况下,Knockout observable 将新值与之前的值进行比较,以确定它是否不同并应该触发更新。它使用equalComparer来做到这一点。默认实现将考虑不同的对象,即使它是同一个实例。

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

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

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

这里有更多关于他们为什么选择以他们的方式为对象实现相等的信息:为什么 Knockout.js 的默认相等比较器将非原始类型视为不相等?

于 2013-06-01T23:57:12.857 回答