使用KnockoutJS过滤分页项目

时间:2014-04-01 04:11:00

标签: javascript jquery knockout.js

我是淘汰赛的新手,到目前为止我喜欢它。我有一个很多问题。我有一个项目,我正在显示来自数据库的消息。这些消息有类别,我希望能够应用分页以及按类别过滤,具体取决于用户在我的单页应用程序的导航端单击的链接。到目前为止,我能够应用分页,如下面的代码所示:

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包含具有私有类别和公共类别的邮件。我希望默认情况下显示公共类别消息,当用户点击私人(收件箱)导航链接时,会显示私人类别消息。就过滤而言,我该如何解决这个问题?我知道我还需要使用模板。

2 个答案:

答案 0 :(得分:0)

您可以尝试在knockout中使用arrayFilter函数。

首先,为您的过滤器添加一个observable(私人/公共):

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

然后修改self.pagedItems computed的返回值:

    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>

答案 1 :(得分: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属性绑定到UI中的复选框。