我不知道为啥我必须在这个淘汰赛 observable 数组上调用 valueHasMutated

Posted

技术标签:

【中文标题】我不知道为啥我必须在这个淘汰赛 observable 数组上调用 valueHasMutated【英文标题】:I don't know why I have to call valueHasMutated on this knockout observable array我不知道为什么我必须在这个淘汰赛 observable 数组上调用 valueHasMutated 【发布时间】:2015-01-04 15:16:26 【问题描述】:

我正在使用 Durandal 框架。我有一个记录器模块,用于显示和存储向用户显示的消息。消息使用 obsArray.push(...) 存储在一个可观察的数组中。

var logMessages = ko.observableArray();
logMessages.push(
            dt: dt,
            tp: type,
            msg: message
        );

那里没问题。同样在这个模块中,我导出 obsArray 变量。

var logger= 
        logMessages: logMessages,
    ;

return logger;

在另一个名为“消息”的模块中,我有一个视图/视图模型,它从记录器获取 obsArray 并显示消息。我在消息 vm 中有另一个名为 _mess 的可观察数组,它是通过执行填充的

_mess(logger.logMessages())

可观察数组 _mess 绑定到我的视图。当我去看风景时,一切都很好。我在记录器中看到了可观察数组“logMessages”的内容。

但是,当我查看视图时,我可以按下一个按钮来调用记录器并导致对数组的推送。数据已添加到数组中,但我的视图不会自动更新。我必须在消息 vm 中的 observable 数组上调用 valueHasMutated,如下所示:

var addMessage = function () 
        logger.show('this is test');
        _mess.valueHasMutated();   // required to see the update appear in the view
    ;

如果我不调用 valueHasMutated,我的视图不会更新。

这似乎是一个非常简单的用例,我可能只是缺少一个步骤或配置。

谢谢

【问题讨论】:

【参考方案1】:

问题在于您设置了 两个 可观察对象来引用同一个数组。这些单独的 observable 有单独的订阅,即使底层数组发生了变化,对一个 observable 数组的更新也不会传播到另一个。

代替

_mess = ko.observableArray();
_mess(logger.logMessages());

_mess = logger.logMessages;

【讨论】:

【参考方案2】:

所以您已经有一个单独的“服务”来执行您的日志功能。服务也直接公开数组。为什么不简单地在消息模块中引用它并将视图直接绑定到它?

例如:

// Logger
var logger= 
        logMessages: logMessages,
    ;

return logger;

// Messages
var messages = 
  this.service = require('path/to/logger');


// Messages View
<ul data-bind="foreach: service.logMessages">
...

这样做可以避免额外的可观察对象或对现有对象的引用,这也有助于保持逻辑隔离和访问方式统一。

【讨论】:

以上是关于我不知道为啥我必须在这个淘汰赛 observable 数组上调用 valueHasMutated的主要内容,如果未能解决你的问题,请参考以下文章

添加自定义图层时训练非常慢。我发现这个张量运算在 cpu 上而不是在 gpu 上运行,我不知道为啥?

我可以等待 fs.readdir 但我不知道为啥

如何在Android中压缩两个Observable?

存储过程不起作用,我不知道为啥

类型“RelayObservable<unknown>”上不存在属性“then”。当我尝试在反应中使用中继获取数据时。我不知道为啥会出现这个错误

我的 WindowsForm 只是忽略了一些代码行,我不知道为啥?