【问题标题】:Knockout's with construct forces an update of the entire htmlKnockout 的 with 构造强制更新整个 html
【发布时间】:2013-06-01 16:53:18
【问题描述】:

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

在我使用 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 代码本身之外,我还没有找到解决方法。这是淘汰赛中的错误吗?建议的解决方案/解决方法是什么?

谢谢!

【问题讨论】:

  • 我在 jsfiddle 中没有看到任何与 Durandal 相关的内容。
  • 没错,imo 的真正问题在于淘汰赛,但 durandal 有点强迫您使用触发此问题的特定架构。基本上我使用路由重定向和我的视图模型的激活功能来相应地采取行动,但是同样的路由强制我的 HTML 被重建。
  • 你能 fork github.com/dFiddle/dFiddle-1.2 并创建一个关于在这种情况下如何使用 Durandal 的小提琴吗?

标签: knockout.js durandal


【解决方案1】:

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

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

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

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

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?

【讨论】:

  • 我明白了,谢谢!我会试试看能不能用这个作为解决方案
猜你喜欢
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
  • 2013-02-21
  • 2021-12-08
  • 2016-06-02
  • 1970-01-01
相关资源
最近更新 更多