2

我有一个包含 50 个项目的可观察数组,使用 foreach 绑定呈现。

我试图理解为什么每个项目呈现的模板都受到if绑定的影响。本质上,我是基于计算的 observable 显示或隐藏我的模板的一大块。这让我觉得渲染时间增加了 70-100%(与使用visible绑定相比)。

Ryan Niemeyer关于此主题的精彩文章表明,将计算对象绑定到if绑定将导致所有内容在每次计算计算的任何部分更新时重新呈现。但是我的计算值在循环遍历可观察数组期间不会改变值。

this.filtersAvailable = ko.computed(function () { 
   return this.searchInfo.searchType() != 'invites' && this.searchInfo.searchType() != 'requests' 
}, this);

为了确保它实际上没有改变,我添加了这个:

this.filtersAvailable.subscribe(function(newVal) { alert("fa" + newVal); });
this.searchInfo.searchType.subscribe(function(newVal) { alert("st" + newVal); });

也就是说,这个计算在比我的可观察数组的单个视图模型更高的级别上定义的,并且在我的模板中的其他位置重复 调用,当然也被我的可观察数组中的每个其他项目调用。

计算出的 observable 的这种重复调用if是否会导致绑定到它的东西重新渲染?

4

2 回答 2

4

一次又一次地访问计算出的 observable 的值不是问题,因为每次都取回缓存的值。听起来您的订阅没有显示频繁更新?

即使值相同,计算也会如此。您可以尝试抛出一个​<code><div data-bind="text: Date()"></div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ code> 在您的if部分中,看看日期的更新是否比您预期的更频繁。

如果一切都一次又一次地重新渲染,那么日期可能会接近相同。对于值为真值的情况,if 绑定的开销稍大一些,因为它获取子元素的副本,然后将副本呈现为模板并对其进行绑定。visible 只会设置显示样式。现在,如果初始值可能为假并且隐藏部分中有很多标记/绑定,if 绑定可以为您提供更好的性能。if 甚至不会渲染它们,虽然可见仍然会绑定,但只是隐藏。

你也可以尝试一个命名模板,在那里你有你的 if。如果您在ifa 中进行foreach操作,那么 KO 必须在每个 foreach 项中一次又一次地将子元素复制为模板。你可以做到<div data-bind="template: { name: 'subItemTmpl', 'if': myFlag, data: subData"></div>

于 2012-10-02T02:13:31.027 回答
1

如果不查看更多代码,就很难对问题所在形成一个好主意。但是,通过使用最新的 Knockout 候选版本,您可能会看到改进,其中包括对if绑定的优化,以消除不必要的重新渲染。可在https://github.com/SteveSanderson/knockout/downloads下载。

于 2012-10-01T19:45:18.157 回答