如何从另一个视图模型计算一个knockout observableArray?

时间:2017-06-27 11:21:23

标签: javascript jquery knockout.js

我正在学习敲门声,所以请耐心等待......

拿这段代码:

HTML:

<div id="itemsContainer">
</div>
<div id="cartContainer">
  <label data-bind="text: totals"></label>
</div>
<div id="items"></div>

Javacript:

function ItemsViewModel() {
  var self = this;
  self.items = ko.observableArray().publishOn("items");
  self.items.push({
    count: 2,
    price: 100
  });
  self.items.push({
    count: 3,
    price: 200
  });
}

function CartViewModel() {
  var self = this;
  self.totals = ko.computed(function() {
    var total = 0;
    $.each(self, function(i, m) {
      total = total + (m.count * m.price);
    });
    return total;
  }, this).subscribeTo("items", true);

}

var itemsVM;
var cartVM;

itemsVM = new ItemsViewModel();
ko.applyBindings(itemsVM, document.getElementById("itemsContainer"));

cartVM = new CartViewModel();
ko.applyBindings(cartVM, document.getElementById("cartContainer"));

coalesce()

我想更新&#34;总计&#34;取决于我在ItemsViewModel.items中放入(或更改)的数据。

我现在被困住了,不知道如何让它发挥作用?

1 个答案:

答案 0 :(得分:3)

我不确定subscribeTo是否适用于您尝试的计算机...快速解决方法是在CartViewModel构造函数内创建(私有)镜像并在其中使用你的computed

function CartViewModel() {
  var self = this;

  var allItems = ko.observableArray([]).subscribeTo("items", true);

  self.totals = ko.computed(function() {
    return allItems().reduce(function(total, m) {
      return total + (m.count * m.price);
      }, 0);
  });
}

注意:我已将$.each替换为Array.prototype.reduce;)

编辑:我在docs中找到了另一个答案:您可以使用转换功能:

function CartViewModel() {
  var self = this;

  self.totals = ko.observableArray([])
    .subscribeTo("items", true, function(items) {
      return items.reduce(function(total, m) {
       return total + (m.count * m.price);
    }, 0);
  });
};

更新了镜像方法:http://jsfiddle.net/qzLkjLL1/

使用转换方法更新了小提琴:http://jsfiddle.net/ynoc6hha/