将另一个observableArray的值合并到KnockoutJS中的现有observableArray中

时间:2014-07-12 21:27:20

标签: ajax knockout.js ko.observablearray

在发出针对类似但不同数据的第二个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添加新值,以便我可以使用新信息更新我的观点。

2 个答案:

答案 0 :(得分:3)

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

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;
      }
   });
});

答案 1 :(得分:0)

为了解决我的问题,我使用了@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。