2014-04-01 66 views
0

我是新來的knockoutJS,到目前爲止我喜歡它。我有許多問題需要解決。我有一個項目,顯示來自數據庫的消息。這些消息有類別,我希望能夠應用分頁以及按類別過濾,具體取決於用戶在單頁應用程序的導航側單擊的鏈接。到目前爲止,我能申請頁面如圖所示下面的代碼:使用KnockoutJS過濾分頁項目

self.pagedItems = ko.computed(function() { 
     var array = ko.observableArray(data.ChannelMessages); 
     var indexOfFirstItemOnCurrentPage = (((self.page() * 1) - 1) * (self.itemsPerPage() * 1));   
     var pageArray = array2.slice(indexOfFirstItemOnCurrentPage, indexOfFirstItemOnCurrentPage + (self.itemsPerPage() * 1)); 
     return pageArray; 
    }); 

pagedItems包含私有類和公共類的消息。我希望默認顯示公共類別消息,並且當用戶點擊私人(收件箱)導航鏈接時顯示私人類別消息。就過濾而言,我如何去做這件事?我知道我將不得不使用模板。

回答

0

你可以嘗試在淘汰賽中使用arrayFilter函數。

首先,添加一個可觀察你的過濾器(私人/公共):

self.filterCategory = ko.observable('Public'); 

然後修改計算您的self.pagedItems的返回值:

var pageArray = ... 
    return ko.utils.arrayFilter(pageArray, function (item) { 
     return item.category === self.filterCategory(); 
    }); 
}); 

請注意,我假定類是您物品的財產。 :-)

稍後,您可以更改filterCategory,計算結果將自動重新計算。

這裏有上arrayFilter一些信息:http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html

回覆額外的信息,您的評論

下面是一個簡單示例中,我寫道:

<!DOCTYPE html> 
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta charset="utf-8" /> 
    <title></title> 
    <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script> 
    <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script> 
    <script> 
     var rawMessages = ko.observableArray([]), 
      category = ko.observable('Public'), 
      pageSize = ko.observable(25), 
      pageIndex = ko.observable(0), 
      filteredMessages = ko.computed(function() { 
       return ko.utils.arrayFilter(rawMessages(), function (m) { 
        return m.category === category(); 
       }); 
      }); 

     // Changing category resets page index. 
     category.subscribe(function() { 
      pageIndex(0); 
     }); 

     // For binding. 
     var model = { 
      pageCount: ko.computed(function() { 
       return Math.ceil(filteredMessages().length/pageSize()); 
      }), 

      messages: ko.computed(function() { 
       var start = pageIndex() * pageSize(); 
       return filteredMessages().slice(start, start + pageSize()); 
      }), 

      back: function() { 
       pageIndex(Math.max(pageIndex() - 1, 0)); 
      }, 

      next: function() { 
       pageIndex(Math.min(model.pageCount() - 1, pageIndex() + 1)); 
      }, 

      category: category 
     }; 

     // Some test data. 
     for (var i = 1; i <= 500; i++) { 
      rawMessages.push({ 
       subject: 'Message number ' + i.toString(), 
       category: ['Public', 'Private'][Math.floor(Math.random() * 2)] 
      }); 
     } 

     $(function() { 
      // DOM is ready now 
      ko.applyBindings(model); 
     }); 
</script> 
</head> 
<body> 

    Page count: <span data-bind="text: pageCount"></span><br /> 
    Page index: <span data-bind="text: pageIndex"></span><br /> 
    Category: <select data-bind="options: ['Public', 'Private'], value: category"></select><br /> 

    <br /> 

    <div data-bind="foreach: messages"> 
     <div> 
      [<span data-bind="text: category"></span>] <span data-bind="text: subject"></span> 
     </div> 
    </div> 

    <br /> 

    <button type="button" data-bind="click: back">Back</button> <button type="button" data-bind="click: next">Next</button> 

</body> 
</html> 
+0

這就像一個魅力,但是我現在具有總頁數計算另一個問題: 代碼self.totalPages = ko.computed(函數(){ 返回Math.ceil(this.messages()長度/ this.itemsPerPage()); },this); this.messages引用未過濾的數組。如果我將其替換爲已過濾和分頁的pagedItems,則總頁數爲1, 我覺得解決方案是過濾頁面,但是如何完成此操作? – cgitosh

+0

我可能會分裂並征服這個問題。有一個原始消息緩衝區,一個過濾的消息緩衝區,然後根據過濾的消息和您的頁面索引/大小計算消息。我在回覆中添加了一個示例。將其保存到.html文件並在瀏覽器中打開。 – Paul

0

像這樣的事情

self.isShowPrivate = ko.observable(false); 
self.pagedItems = ko.computed(function() { 
    var array = ko.observableArray(data.ChannelMessages); 
    var indexOfFirstItemOnCurrentPage = (((self.page() * 1) - 1) * (self.itemsPerPage() * 1)); 
    var pageArray = getMessages(indexOfFirstItemOnCurrentPage, indexOfFirstItemOnCurrentPage + (self.itemsPerPage() * 1), self.isShowPrivate()); 
    function getMessages(ParameterizedThreadStart, end, showPrivate) 
    { 
     if (showPrivate) 
     // your logic to get private as well as public 
     esle 
     // your logic to get public only 
    } 
    return pageArray; 
}); 

您需要將isShowPrivate屬性綁定到用戶界面中的複選框。