如何处理Knockout的分页 [英] How to handle pagination with Knockout

查看:148
本文介绍了如何处理Knockout的分页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个设置为绑定到 observeableArray 的div,但我只想显示来自 observeableArray的最多50个项目在任何给定时间。我想通过页面上的上一个和下一个按钮以及索引来处理这个问题,以允许用户循环浏览集合中的项目页面。
我知道我可以用 computedObservable 和一个自定义数据绑定,但我不知道该怎么做(我仍然是一个淘汰赛新手)。
谁能指出我正确的方向?

I have a div that is setup to bind to a observeableArray ,but I only want to show at most 50 items from that observeableArray at any given time. I want to handle this with pagination with a previous and next button along with indices on the page to allow users to cycle through pages of items from the collection.
I know I could probably do this with a computedObservable and a custom data binding but I'm not sure how to do it (I'm still a Knockout neophyte).
Can anyone point me in the right direction?

这是我的代码(JS在TypeScript中):

Here is my code (the JS is in TypeScript):

<div class="container-fluid">
    <div class="row-fluid">
        <div class="span12">
            <%=
            if params[:q]
              render 'active_search.html.erb'
            else
              render 'passive_search.html.erb'
            end
            %>
            <%= form_tag("/search", method: "get", :class => "form-search form-inline") do %>
            <%= label_tag(:q, "Search for:") %>
            <%= text_field_tag(:q, nil, class:"input-medium search-query") %>
            <%= submit_tag("Search", :class=>"btn") %>
            <% end %>

            <div class="media" data-bind="foreach: tweetsArray">
                <%= image_tag('twitter-icon.svg', :class=>"tweet_img", :style=>"display:inline;") %>
                <div class="media-body" style="display:inline;">
                    <h4 class="media-heading" data-bind="text: user.screen_name" style="display:inline;"></h4>
                    <span data-bind="text:text" style="display:inline;"></span> <br />
                    <span data-bind="text:'Created at '+created_at"></span> <br />
                </div>
            </div>

            <div class="pagination pagination-centered">
                <ul>
                    <li>
                        <a href="#">Prev</a>
                    </li>
                    <li>
                        <a href="#">1</a>
                    </li>
                    <li>
                        <a href="#">Next</a>
                    </li>
                </ul>
            </div>

        </div>
    </div>
</div>

<script>
    var viewModel = new twitterResearch.TweetViewModel();
    ko.applyBindings(viewModel);

    //TODO: notes to self, use custom binding for pagination along with a computed observable to determine where at in the list you are

    //document.onReady callback function
    $(function() {
        $.getJSON('twitter', {}, function(data) {
            viewModel.pushTweet(data);
            console.log(data.user);
        });
    });
</script>

declare var $: any;
declare var ko: any;

module twitterResearch {
    class Tweet {
        text: string;
        created_at: string;
        coordinates: string;
        user: string;
        entities: string;
        id: number;
        id_str: string;

        constructor(_text: string, _created_at: string, _coordinates: any, _user: any,
                    _entities: any, _id_str: string, _id: number){

            this.text = _text;
            this.created_at = _created_at;
            this.coordinates = _coordinates;
            this.user = _user;
            this.entities = _entities;
            this.id_str = _id_str;
            this.id = _id;
        }
    }

    export class TweetViewModel{

        tweetsArray: any;
        constructor()
        {
            this.tweetsArray = ko.observableArray([]);
        }

        //tweet is going to be the JSON tweet we return
        //from the server
        pushTweet(tweet)
        {
            var _tweet = new Tweet(tweet.text, tweet.created_at, tweet.coordinates,
                                    tweet.user, tweet.entities, tweet.id_str, tweet.id);
            this.tweetsArray.push(_tweet);
            this.tweetsArray.valueHasMutated();
        }
    }
}


推荐答案

使用Knockout进行分页非常简单。我个人会这样做:

Pagination is quite simple with Knockout. I would personally achieve it this way:


  • 有一个包含所有元素的observableArray

  • 有一个包含当前页面的observable(初始化为0)

  • 有一个变量声明每页元素的数量

  • 有一个计算结果返回的数字页面,由于每页元素的数量和元素的总数而计算。

  • 最后,添加一个计算切片包含所有元素的数组。

  • Have an observableArray containing all your elements
  • Have an observable containing the current page (initialized to 0)
  • Have a variable declaring the number of elements per page
  • Have a computed that returns the number of pages, calculated thanks to the number of elements per page and the total number of elements.
  • Finally, add a computed that slices the array containing all the elements.

鉴于此,您现在可以添加一个递增(下一个)或递减(前一个)当前页面的函数。

Given that, you can now add a function that increments (next) or decrements (previous) the current page.

这是一个简单的例子:

var Model = function() {
    var self = this;
    this.all = ko.observableArray([]);
    this.pageNumber = ko.observable(0);
    this.nbPerPage = 25;
    this.totalPages = ko.computed(function() {
        var div = Math.floor(self.all().length / self.nbPerPage);
        div += self.all().length % self.nbPerPage > 0 ? 1 : 0;
        return div - 1;
    });

    this.paginated = ko.computed(function() {
        var first = self.pageNumber() * self.nbPerPage;
        return self.all.slice(first, first + self.nbPerPage);
    });

    this.hasPrevious = ko.computed(function() {
        return self.pageNumber() !== 0;
    });

    this.hasNext = ko.computed(function() {
        return self.pageNumber() !== self.totalPages();
    });

    this.next = function() {
        if(self.pageNumber() < self.totalPages()) {
            self.pageNumber(self.pageNumber() + 1);
        }
    }

    this.previous = function() {
        if(self.pageNumber() != 0) {
            self.pageNumber(self.pageNumber() - 1);
        }
    }
}

你会发现一个简单的这里有完整的例子: http://jsfiddle.net/LAbCv/ (可能有点儿马车,但是想法就在那里。

You'll find a simple and complete example here: http://jsfiddle.net/LAbCv/ (might be a bit buggy, but the idea is there).

这篇关于如何处理Knockout的分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆