问题标签 [computed-observable]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
240 浏览

javascript - 在计算观察者中聚合数组数据,但在 KnockoutJS 中维护状态

这是一个相当复杂的问题。我试图将代码尽可能地改进为仅演示问题所需的代码。这是一个很长的帖子 - 考虑一下自己被警告了!

这个问题的工作演示可以在这个jsFiddle中看到。


我要做的是根据数组中项目的共同属性将数组聚合成组。实际上将数组聚合成组是相当简单的:

transformObjectIntoArray可以在 jsFiddle 示例中看到。它只是通过基本摆脱属性将一个对象变成一个数组。

这需要一组数据,例如:

将其转换为以下对象:

然后将其转换为以下数组:

到目前为止,一切都按预期工作,如 jsFiddle 所示。

当我向数据数组添加一个新元素时,问题就开始了。vm是我ViewModel在以下代码中的实例

正如您可能已经猜到的那样,这会导致计算的 observableview执行,从而重新聚合底层数据数组。所有新Group对象都被创建,这意味着与它们相关的任何状态信息都将丢失。

这对我来说是个问题,因为我存储了它们是否应该在Group对象上展开或折叠的状态:

因此,由于它们被重新创建,该状态信息就会丢失。因此,所有组都恢复到其默认状态(折叠)。


我知道我面临的问题。但是,我正在努力想出一个并不笨拙的解决方案。我想到的可能的解决方案包括:

维护组状态图

我的第一个想法是创建一个可以用作地图的对象。它将使用 groupId 作为键名,状态将是值:

即使每次添加元素时都会重新创建组,但GroupState仍会持续存在。我无法解决的一个问题是如何从GroupState地图中删除不再存在的组。

例如,

与当前地图someNewArray中的项目相对应的没有 groupIds 的项目数组在哪里。GroupState我将如何删除不再有参考的条目?这似乎是我的应用程序中的内存泄漏。

这个问题可以在这个jsFiddle看到。注意,单击按钮后,组状态大小增长到 5 个元素,但只有 3 个组。这是因为尽管不再使用原始的 2 组,但并未删除。

维护一个 viewState 数组并移除计算的 observable

我的第二个想法是删除计算的 observable view。相反,我有第二个可观察的数组,称为它被聚合到当前“视图”之后viewState的数组。data然而,我很快就遇到了这个想法的问题。

首先,我必须编写几个方法来维护两个数组之间的状态:add()remove()clear()等。考虑到必须这样做,我立即开始质疑拥有第二个数组是否是个好主意。

其次,删除计算数组意味着线性搜索viewState数组以查看是否有任何当前元素包含与传入项相似的 groupId。虽然在实践中,这会非常快,但我不喜欢在每个 add ( O(n)vs O(1)) 上迭代整个数组的理论。在路上,我可能会处理成千上万的项目。


我觉得可能有一个简单的解决方案,但我正在努力解决这个问题。有没有人有任何想法可以帮助解决这个问题,或者知道用 KnockoutJS 完成这个更好的方法?也许,我上面的一个想法会增加一些洞察力(我仍然觉得GroupState地图在正确的轨道上)

如果我遗漏了一些重要信息,请告诉我,我会尽力补充

0 投票
1 回答
357 浏览

knockout.js - KnockoutJs observable array 通过计算 observable 和节流

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

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

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

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

0 投票
1 回答
385 浏览

javascript - 如何在淘汰赛js中访问observablearray的ko.computed方法

我想获得 work_time 值。如何访问该值?

0 投票
1 回答
63 浏览

knockout.js - 挖空 viewModel 属性

在尝试了几个小时的想法之后,我无法让它发挥作用。

简单的需求:我有一个文本框(输入类型 TEXT)和一个 Div 标签:

理想情况下,我要做的就是在每次用户在 tb 文本框中键入新字符时更新 WordCount。

为此,我创建了一个 ViewModel:

我正在使用的 CountWords 函数如下所示:

上面的技术是我在另一个 SO 帖子中看到的一种解决方案——一种获取计算出的 ko 值以按需刷新/更新的方法。这个想法是从按键函数调用 recalcWordCount 。但问题是我的 recalcWordCount 函数在我的 ViewModel 对象中——并且 Knockout 已经创建了一个实例。我不知道如何获取 ko 的 ViewModel 实例以调用该函数。例如,这不起作用:

此外,这不起作用:

此外,这不起作用:

我将不胜感激有关如何使其工作的任何建议。

0 投票
1 回答
39 浏览

knockout.js - 有没有办法在 ajax 调用上修改请求的数据?

我有一个淘汰脚本,它通过 ajax 从服务器加载数据并将此信息输出到模型中。如果为了简化一切,我的模型如下所示:

一切正常(我的视图中填充了来自服务器的信息)。但我需要修改这些信息(例如将数据从时间戳更改为人类可读格式)。

据我了解,实现它的一种方法是通过淘汰计算 observables,但我没有看到这样做的原因,因为我在这里永远不需要时间戳,我可以在更新后更改我的数据并使用它(如果我是错了,我很高兴听到为什么以及如何使用计算出的 observables 来实现我想要的)。

因此,我尝试通过以下方式更改有关 ajax 请求的数据(一切都相同,但 ajax 调用有回调):

我在页面上没有错误,但没有显示任何信息。当我转到其他页面时,我看到一个警告:TypeError {stack: (...), message: "500 Error get /#Home Property 'articleInfo' of object #<ArticleViewModel> is not a function"}

我究竟做错了什么?

0 投票
1 回答
91 浏览

knockout.js - 为什么我的计算函数没有被添加到我的淘汰赛可观察数组中的每个项目中?

我的可观察数组有两行(项目?),行 [0] 有 pid = 2; 行 [1] 的 pid = 3。

我正在尝试向名为 cartItems 的可观察数组添加一个字段。这应该类似于向 Excel 电子表格或数学矩阵添加一列。

以下代码不会产生任何错误,但也不会计算 self.myTest 值( i5 总是得到默认答案为零。为什么?

0 投票
1 回答
884 浏览

select - 自动复位