【问题标题】:Merge value from another observableArray into existing observableArray in KnockoutJS将另一个 observableArray 中的值合并到 KnockoutJS 中的现有 observableArray
【发布时间】:2014-07-13 21:07:57
【问题描述】:

在针对类似但不同的数据发出第二次 AJAX 请求后,我无法弄清楚如何添加到预先存在的 observableArray

我的第一个 JSON 请求不包含名为 value 的类型,所以我需要添加它。我最初的 JSON 结构:

[{"statusmsg":"OK","data":{"status":"stopped"},"sender":"hostname","statuscode":0}]

发出第二个 AJAX 请求,从 REST 服务器获取服务的正常运行时间:

[{"statusmsg":"OK","data":{"value":"","fact":"some_fact"},"sender":"hostname","statuscode":0}

我想向嵌套对象data 添加类型value,其中包含some_fact

我尝试了以下方法:

ko.utils.arrayForEach(self.rows(), function(row) {
   ko.utils.arrayForEach(self.timeRows, function(time) {
      if(row.sender() == time.sender()) {
         self.rows()[0].data.push({value: time.data.value()});
      }
   });
});

注意:我使用占位符索引 0 仅用于测试。理想情况下,我只想根据主机名找到匹配项并更新observableArray

当这段代码执行时,我收到了错误

TypeError: self.rows(...)[0].data.push 不是函数

我也尝试在data 旁边加上括号,比如data().push,但这也不起作用。

目的是为原始observableArray 添加一个新值,称为rows,以便我可以使用新信息更新我的视图。

【问题讨论】:

  • 取决于您如何在视图模型中定义rows。它只是包装在 ko.observableArray() 中的简单 JS 对象数组吗?您是否对从服务器收到的数据使用了 ko.mapping.fromJSON() 或 ko.mapping.fromJS()?您是否制作了自己的自定义模型来查看模型映射?
  • @Sybeus:我使用了 ko.mapping.fromJSON。我没有制作定制模型。只有一个 ViewModel

标签: ajax knockout.js ko.observablearray


【解决方案1】:

由于您选择了默认的 Knockout 映射,它会自动假定关联数组是具有属性的简单对象,因此没有数组原型函数,例如 push()。您也不需要索引引用,因为您已经在self.rows() 中找到了row。所以只需简单地设置匹配row对象的“数据”子对象的value属性:

ko.utils.arrayForEach(self.rows(), function(row) {
   ko.utils.arrayForEach(self.timeRows, function(time) {
      if(row.sender() == time.sender()) {
         row.data.value = time.data.value;
      }
   });
});

【讨论】:

  • 哦,哇,我不知道你能做到这一点。我认为由于第一组中不存在值,因此您必须以某种方式创建它。
  • 它是 JavaScript 最强大的功能之一,能够为现有对象动态添加属性和函数。
  • 在下方查看我的回答,了解在您提供帮助后我必须做什么。
  • 我以为你只是想先构建一个对象列表,然后绑定到它。如果data 是每行信息的真正动态子列表,并且随着时间的推移对子列表进行 AJAX 更新,那么我建议采用完全不同的方法。像jsfiddle.net/Hg2cF 这样的东西,这样您就不必求助于黑客来让您的视图模型更新视图。 Knockout 就是从视图模型自动更新视图,所以如果您发现自己必须自己编写该部分,那么您就违背了 Knockout 的目的。
【解决方案2】:

为了解决我的问题,我使用了@Sybeus' answer,但后来我意识到我的 UI 中的行没有更新,因为我的 UI 绑定到了旧版本的行。即使我尝试创建一个虚拟订阅者并通知我的计算 observable 行已更新,它仍然绑定到旧行,如 this answer 中所述:

如果你想替换数组,你可能应该创建一个 替换数组,将推文推入该数组,最后替换 通过 self.tweets(replacementArray); 在 observableArray 中创建数组。

所以我必须做的是:

self.updateServiceStartTime = function() {
  var url = "url";

  $.ajax({
     method: "GET",
     url: url,
     success: function(data) {
        var observableData = ko.mapping.fromJSON(data);
        var array = observableData();
        self.timeRows(array);

        ko.utils.arrayForEach(self.rows(), function(row) {
           ko.utils.arrayForEach(self.timeRows(), function(time) {
              if(row.sender() == time.sender()) {                    
                 if (time.data.value()) {
                    row.data.value = time.data.value;
                 }
                 else {
                    row.data.value = "No time found yet.";
                 }
              }
           });
        });
        self.cloneRows(self.rows().slice());
        self.rows.removeAll();
        self.rows(self.cloneRows().slice());
     }
  });
  };

这会使用我添加的新数据更新 UI。

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    相关资源
    最近更新 更多