[英]Knockout Filtering on Observable Array
我已經開始學習Knockout了,我在按鈕點擊過濾可觀察數組並顯示結果時遇到了一些麻煩。
這是我的模特:
function Product(data) {
this.id = data.id;
this.name = data.name;
this.price = data.price;
this.description = data.desc;
this.image = data.image;
this.genre = data.genre;
this.show = data.show;
this.offer_desc = data.offer_desc;
this.offer_id = data.offer_id;
}
function ProductModel() {
var self = this;
self.products = ko.observableArray([]);
$.getJSON('../PHP/Utilities.php?json=true', function(json) {
var mappedProducts = $.map(json, function(item) { return new Product(item) });
self.products(mappedProducts);
});
self.filterProducts = ko.computed(function(genre) {
if(typeof genre === 'undefined') {
return self.products(); //initial load when no genre filter is specified
} else {
return ko.utils.arrayFilter(self.products(), function(prod) {
return prod.genre = genre;
});
}
});
}
ko.applyBindings(new ProductModel());
這是html:
<div data-bind="foreach: filterProducts">
<div class="row">
<div class="col-md-2">
<img data-bind="attr:{src: '../images/' + image, alt: name}" />
</div>
<div class="col-md-2" data-bind="text: name"></div>
<div class="col-md-1" data-bind="text: price"></div>
<div class="col-md-3" data-bind="text: description"></div>
<div class="col-md-1" data-bind='text: offer_id'>
<div class="col-md-2" data-bind="text: genre"></div>
<div class="col-md-1" data-bind="text: show"></div>
</div>
</div>
我也不確定如何綁定點擊功能來過濾類型上的產品。 我認為這樣的事情......但它不起作用
<button data-bind="click: filter('1')"> Filter </button>
self.filter = function(genre) {
self.filterProducts(genre);
}
你不能在ko.computed
有一個帶參數的ko.computed
。
您需要的是將當前過濾器存儲在新屬性中並在計算中使用它
function ProductModel() {
var self = this;
self.products = ko.observableArray([]);
self.currentFilter = ko.observable(); // property to store the filter
//...
self.filterProducts = ko.computed(function() {
if(!self.currentFilter()) {
return self.products();
} else {
return ko.utils.arrayFilter(self.products(), function(prod) {
return prod.genre == self.currentFilter();
});
}
});
}
在您的click
處理程序中,只需設置當前過濾器:
<button data-bind="click: function() { filter('1') }"> Filter </button>
self.filter = function(genre) {
self.currentFilter(genre);
}
演示JSFiddle
如果你想在click
綁定中傳遞額外的參數a(參見文檔中 ),請注意function() { }
,否則Knockout會在解析綁定時執行你的函數,而不是在你點擊按鈕時執行。
首先,你誤解/使用computed Observables
。 來自KnockoutJS文檔 :
這些是依賴於一個或多個其他可觀察對象的函數,並且只要這些依賴關系中的任何一個發生更改,它們就會自動更新。
您計算的可觀察filterProducts
器products
依賴於您不會更改的可觀察數組products
,您只需讀取它的值即可。 因此,沒有任何內容可以通知filterProducts
進行重新評估。
那么,什么是快速簡單的修復?
filterProducts
將依賴的新的可觀察對象filteredGenre
。 filterProducts
以便檢查filteredGenre
的值並基於它返回過濾后的產品。 filter
功能,以便在獲得新genre
時更改filteredGenre
,這將導致重新評估計算的filterProducts
我希望你有這個主意。
您可能想看看原始淘汰賽作者的Knockout Projections插件。 它在具有大型集合的場景中具有性能優勢。 有關詳細信息,請參閱blogpost 。
self.filterProducts = self.products.filter(function(prod) {
return !self.currentFilter() || prod.genre == self.currentFilter();
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.