KnockoutJs observable array 通过计算 observable 和节流

Posted

技术标签:

【中文标题】KnockoutJs observable array 通过计算 observable 和节流【英文标题】:KnockoutJs observable array via computed observable with throttle 【发布时间】:2014-02-27 11:48:15 【问题描述】:

我有一个问题,我有一个底层的 observable 数组,它通过计算的 observable 进行排序和公开。虽然我现在有一个问题,如果我限制计算的 observable,在底层数组上调用 removeAll 时似乎会导致问题。

场景非常复杂,但基本上我在缓冲区部分中有一组大约 0-200 行,这是可观察的数组,然后我根据用户选择的选项卡显示该数组的部分。因此,在 100 条记录中,我只能在计算的 observable 中将其过滤到 30 条。但有些地方我需要使数组无效并下载一个新列表,该列表可能会单独或分批下降,因此会受到限制以减少不必要的重新评估。但是,当我尝试使用 removeAll 使底层数组无效时,它似乎通知视图内容已更改并尝试重新评估视图级别绑定,但是其中一些查看现在为空的底层数组,但作为计算的没有赶上它跌倒了。

那么有没有办法在数组上的 removeAll 之后强制计算计算?

这是我的意思的一个例子:

var currentFilterType = ko.observable(1); // this is changed in the UI by the user
var underlyingArray = ko.observableArray();
var filteredDetails = ko.computedObservable(filterPredicate);

function filterPredicate() 
   // assume ko.linq is included, this is a simple version of whats happening
   return underlyingArray.Where(function(x) return x.FilterType() == currentFilterType; )
                         .OrderBy(function(x) return x.DateCreated(); )
                         .ToObservableArray();


function invalidateData() 
   underlyingArray.removeAll();
   // fetch some more data to repopulate array


function doSomethingWithItem(data) 
   // check something against the original array


// In the view usage would look like this
<!-- ko foreach: filteredDetails -->
   <a data-bind="click: doSomethingWithItem"></a> 
<!-- /ko -->

【问题讨论】:

一些代码可能会有所帮助。但是根本看不到任何代码,也许可以在计算的 observable 的开头使用另一个 observable 来控制其余计算的执行。 这是一个精心设计的场景,我可以展示基础知识,但是很难展示它的每一部分。将编辑问题以更好地显示问题。 你为什么要做removeAll?当您再次从服务器获取数据时,只需将其分配给原始数组即可。淘汰赛将负责其余的工作。 你能充实一下filterPredicate函数吗 @CtrlDot 原因是不是每个服务器更新都需要使集合失效。它在某种程度上有点像聊天室,所以每次有新消息进入时,它都会附加到列表中。所以它不会想在这一点上清除。但是,如果用户想要转到上一个聊天页面,他们需要清除他们当前的数据集,然后加载新的数据集。所以不是每个服务器请求都会导致removeAll() 【参考方案1】:

我认为问题出在 shouldBeVisible 函数上。如果它读取了底层数组 observable,那么该可见绑定将依赖于该 observable。当您调用 removeAll 时,可见绑定将更新。

如果您限制计算,filteredDetails 将延迟重新计算,但 shouldBeVisible 将立即重新评估。

shouldBeVisible 函数接受一个数据实例,但在可见绑定执行该函数时没有传递任何内容。此函数也不应访问所传递数据之外的任何内容。

首先更改从过滤详细信息中传入当前项目的可见绑定,然后评估条件。如果你需要使用底层数组 observable,使用 .peek() 来避免依赖。 filterDetails 将最终重新计算。

<!-- ko foreach: filteredDetails -->
   <div data-bind="visible: shouldBeVisible($data)"></div> 
<!-- /ko -->

【讨论】:

对不起,编码错误是我的错,它实际上是一个点击处理程序,它会在迭代中自动传递当前项目,并将更新代码以反映这一点。

以上是关于KnockoutJs observable array 通过计算 observable 和节流的主要内容,如果未能解决你的问题,请参考以下文章

KnockoutJS 查找 ko.observable() 长度

KnockoutJs observable array 通过计算 observable 和节流

为啥我的 knockoutjs 计算 observable 不起作用?

knockoutjs 图像 src 未从 ko.observable 更新

KnockoutJS Observable 未在模板中更新

如何在 KnockoutJS 中访问 ViewModel 之外的 observable?