簡體   English   中英

可觀察數組上的Knockout過濾

[英]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文檔

這些是依賴於一個或多個其他可觀察對象的函數,並且只要這些依賴關系中的任何一個發生更改,它們就會自動更新。

您計算的可觀察filterProductsproducts依賴於您不會更改的可觀察數組products ,您只需讀取它的值即可。 因此,沒有任何內容可以通知filterProducts進行重新評估。

那么,什么是快速簡單的修復?

  1. 定義filterProducts將依賴的新的可觀察對象filteredGenre
  2. 更改filterProducts以便檢查filteredGenre的值並基於它返回過濾后的產品。
  3. 更改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.

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