簡體   English   中英

Knockout計算可觀察數組的項目

[英]Knockout computed items of observable array

我有以下ViewModel:

var myViewModel = {
  categories: ko.observableArray([
    { name: ko.observable('Fruit'), 
      items: ko.observableArray([ 
        ko.observable('Apple'),
        ko.observable('Orange'), 
        ko.observable('Banana'), 
      ]),
    },
  ]),
};

我想為這個數組的每個項添加一個計算值:

$.each(myViewModel.categories(), function(index, cat){
  cat.num = ko.computed(function(){
    return cat.items().length;
  }, cat);
});

這是我的HTML:

<ul data-bind="foreach: { data: categories, as: 'category' }">
    <li>
        <ul data-bind="foreach: { data: items, as: 'item' }">
            <li>
                <span data-bind="text: category.name"></span>:
                <span data-bind="text: item"></span>
            </li> 
        </ul>
      <span data-bind="text: category.num"></span>
    </li>
</ul>

它的效果非常好! 結果如下:

Fruit: Apple
Fruit: Orange
Fruit: Banana
3

但現在讓我們說我的數據發生了變化,我需要反映這些變化:

myViewModel.categories([
  {
    name: "Fruit",
    items: ["Apple", "Banana"],
  },
  {
    name: "Veg",
    items: ["Potato", "Carridge"],
  }
]);

它不起作用 - 我沒有在每個列表的末尾看到num 你能幫我解決這個問題嗎? 這是codepen

當然它不起作用,因為你要替換observableArray的整個內容。 你的這個代碼:

$.each(myViewModel.categories(), function(index, cat){
    cat.num = ko.computed(function(){
        return cat.items().length;
    }, cat);
});

num屬性添加到調用時數組中存在的項目。 通過執行以下操作,為您的observableArray提供一個新的后備數組:

myViewModel.categories([
  {
    name: "Fruit",
    items: ["Apple", "Banana"],
  },
  {
    name: "Veg",
    items: ["Potato", "Carridge"],
  }
])

當然,你丟失舊的數組,從而丟失了在項目而不是可觀察數組上定義的計算的observable。 Knockout當然無法知道如何以及是否應該將計算屬性添加到新數組中的每個項目。

解:

當您替換observableArray的后備數組時,您可以執行相同的屬性添加,如下所示:

myViewModel.categories([
  {
    name: "Fruit",
    items: ["Apple", "Banana"],
  },
  {
    name: "Veg",
    items: ["Potato", "Carridge"],
  }
]);
$.each(myViewModel.categories(), function(index, cat){
    cat.num = ko.computed(function(){
        return cat.items().length;
    }, cat);
});

或者更好的是,您可以使用已定義的屬性實例化數組中的對象。 注意:您不必為每個項目反復編寫函數,例如,您可以為數組項定義構造函數:

function Category(name, items) {
  var self = this;

  this.name = name;
  this.items = ko.observableArray(items);
  this.num = ko.computed(function() {
    return self.items().length;
  });
};

然后,這就是你創建一個新的方法:

var newItem = new Category('Category 1', [ 'Apple', 'Banana']);

並將其插入可觀察數組:

myViewModel.categories.push(newItem);

這會添加一個項目並保留現有項目,或者,如您所做的那樣,您可以提供一個全新的數組:

myViewModel.categories([
  new Category('Fruit', ['Apple', 'Banana' ]),
  new Category('Veg', ['Potato', 'Carridge' ])
]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM