我不知道为什么我必须在这个挖空可观察数组上调用valueHasMutated

时间:2014-11-07 18:38:13

标签: knockout.js binding durandal mutated

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

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

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

var logger= {
        logMessages: logMessages,
    };

return logger;

在另一个名为“messages”的模块中,我有一个view / viewmodel,它从记录器中获取obsArray并显示消息。我在消息vm中有一个名为_mess的另一个可观察数组,它由

填充
_mess(logger.logMessages())

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

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

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

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

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

由于

2 个答案:

答案 0 :(得分:3)

问题是你已经设置了两个 observable来引用同一个数组。这些单独的observable具有单独的订阅,即使底层数组已更改,一个可观察数组上的更新也不会传播到另一个。

而不是

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

_mess = logger.logMessages;

答案 1 :(得分:1)

所以你已经有一个单独的"服务"做你的日志功能。服务也直接公开了Array。为什么不在消息模块中引用它并直接将视图绑定到它?

E.g:

// Logger
var logger= {
        logMessages: logMessages,
    };

return logger;

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

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

通过这样做,您可以避免使用其他可观察对象或现有对象的引用,这也有助于保持逻辑孤立和访问统一的方式。