Knockout:如何将可观察数组订阅到另一个属性的给定属性?

时间:2016-11-04 16:26:15

标签: knockout.js match subscribe

这是我的viewmodel包含2个可观察数组:

function VM() 
{
    var self = this;

    self.A = ko.observableArray([
    {"ID": 1, "Name": "one"}, 
    {"ID": 2, "Name": "two"}, 
    {"ID": 3, "Name": "three"}
    ]);

    self.B = ko.observableArray([
    {"ID": 1, "Name": "one", "Description":"description of One"},
    {"ID": 2, "Name": "twoB","Description":"description of two"}, 
    {"ID": 3, "Name": "three","Description":"description of three"}
   ]);

};

我需要的是......当"姓名" observableArray" B"中的属性更改,它必须更新"名称" observableArray" A"的属性。

实际上,我这样做了:

    ko.utils.arrayForEach(self.B(), function (item) {                
        for (var index = 0; index < self.A().length; index++) {
            if (self.A()[index].ID == item.ID)
                if (self.A()[index].Name !== item.Name)
                    self.A()[index].Name = item.Name ; 
        }
    }); 

我的问题:A是否有可能订阅B,所以当&#34; name&#34; B,A的变化会更新吗?什么是最好的方法 ?我必须使用&#34; ko.computed&#34;相反?

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

您可以为数据定义observable变量,然后利用computed observable’s evaluator这样计算出的可观察函数跟踪其依赖关系,您将能够更新其他数组的可观察量

请查看此示例:https://jsfiddle.net/kyr6w2x3/107/

  var dataA = [{"ID": 1, "Name": "one"}, {"ID": 2, "Name": "two"}, {"ID": 3, "Name": "three"}];
  var dataB = [{"ID": 1, "Name": "one", "Description":"description of One"}, {"ID": 2, "Name": "twoB","Description":"description of two"}, {"ID": 3, "Name": "three","Description":"description of three"}];
  var AppViewModel = function(){
     var self = this;
     self.A = ko.observableArray([]);
     self.B = ko.observableArray([]);
        self.A($.map(dataA, function (item) {
            return new ItemViewModel (item,self);
      }));

      self.B($.map(dataB, function (item) {
        return new ItemViewModel (item,self);
      }));
    }

    var ItemViewModel = function(data,AppVM){
      var self = this;
      self.ID = ko.observable(data.ID);
      self.Name = ko.observable(data.Name);
      self.Description = ko.observable(data.Description);
      self.UpdateA = ko.computed(function () {
        ko.utils.arrayFirst(AppVM.A(), function (item) {
          item.ID() === self.ID() ? item.Name(self.Name()) :"";
        });   
      }, self);
    }
    var VM = new AppViewModel();
    ko.applyBindings(VM);

您不会看到ArrayA和ArrayB的名称可观察之间存在任何差异,因为一旦其依赖关系被更新,计算函数就会被触发(您会感觉到(A,B)的名称相同时页面正在加载)。你可能想要考虑只使用一个数组而不是两个,因为ID和Name是相同的,然后你不再需要使用计算函数了!