6

我正在创建一个流式分页视图列表。我们以空集合启动应用程序,并定期将项目添加到集合中。当集合的大小通过 page_size 属性时,其余模型不应被渲染,但复合视图应添加页码以单击。

我计划为我的复合视图创建一个渲染函数,它只根据当前页面#和页面大小渲染项目,在我的集合中有一个函数,它返回一个模型列表,如下所示:

get_page_results: function(page_number){
    var all_models = this.models;

    var models_start = page_number * this.page_size;
    var models_end = models_start + this.page_size;

    //return array of results for that page
    return all_models.slice(models_start,models_end);
}

我的问题是,我是否应该为此使用 Marionette 的复合视图?似乎我覆盖了 Marionette 的 collectionView 的大部分功能以获得我想要的东西。

每次我的收藏中的项目数量发生变化时,需要更新两件事:

  • 集合视图中的 itemViews
  • 复合视图底部的页码
4

2 回答 2

3

我强烈建议不要在视图层执行此操作。您将在视图中添加大量代码,并且最终会在多个视图之间复制大量代码(一个用于显示数据,一个用于页面列表和计数,一个用于... )。

相反,使用装饰器模式来构建一个知道如何处理的集合。我这样做是为了过滤、排序和分页数据,效果很好。

例如,这是我设置过滤的方式(在 JSFdiddle 中运行:http: //jsfiddle.net/derickbailey/vm7wK/


function FilteredCollection(original){
    var filtered = Object.create(original);

    filtered.filter = function(criteria){
        var items;
        if (criteria){
            items = original.where(criteria);
        } else {
            items = original.models;
        }
        filtered.reset(items);
    };        

    return filtered;
}

var stuff = new Backbone.Collection();

var filtered = FilteredCollection(stuff);
var view = Backbone.View.extend({
    initialize: function(){
        this.collection.on("reset", this.render, this);
    },

    render: function(){
        var result = this.collection.map(function(item){ return item.get("foo"); });
        this.$el.html(result.join(","));
    }
});

在您的情况下,您不会像这样进行过滤......但是分页和流式传输的想法是相同的。

您将在“PagingCollection”中跟踪您所在的页面,然后当您的原始集合被重置或添加了新数据时,PagingCollection 函数将重新计算最终 pagedCollection 实例中需要哪些数据,并且使用您需要的数据重置该集合。

像这样的东西(虽然这是未经测试和不完整的。你需要填写一些细节并根据你的应用程序的需要充实它)


function PagingCollection(original){
    var paged = Object.create(original);
    paged.currentPage = 0;
    paged.totalPages = 0;
    paged.pageSize = 0;

    paged.setPageSize = function(size){
      paged.pageSize = size;
    };

    original.on("reset", function(){
      paged.currentPage = 0;
      paged.totalPages = original.length / paged.pageSize;
      // get the models you need from "original" and then
      // call paged.reset(models) with that list
    });

    original.on("add", function(){
      paged.currentPage = 0;
      paged.totalPages = original.length / paged.pageSize;
      // get the models you need from "original" and then
      // call paged.reset(models) with that list
    });

    return paged;
}

使用分页信息装饰集合后,将分页集合传递给 CollectionView 或 CompositeView 实例。这些将正确呈现您传递给它的集合中找到的模型。

关于 CollectionView 与 CompositeView ... CompositeView 是一个 CollectionView(它直接从它扩展),它允许您围绕集合呈现模型/模板。这是主要的区别......它们都处理集合,并从该集合中呈现视图列表。

于 2013-02-13T14:21:08.753 回答
0

我们已经构建了一组bakcbone.marionette你可能会觉得有用的 mixin ( https://github.com/g00fy-/marionette.generic/ )

您可以使用 PaginatedMixin,它允许对 Backbone 集合进行分页 + PrefetchMixin,因此您不必将预取集合传递给视图。

您需要做的唯一代码是:

YourListView = Generic.ListView.mixin(PaginatedMixin,LoadingMixin,PrefetchMixin).extend({
    paginateBy:10,
    template:"#your-list-template",
    itemViewOptions:{template:"#your-itemview-template"},
    fetchPage:function(page){
        this.page = page;
        return this.collection.refetch({data:{page:page}}); // your code here
    },
    hasNextPage:function(){
      return true; // your code here
    },
});

有关工作示例,请参见https://github.com/g00fy-/stack.reader/blob/master/js/views.js

于 2013-02-13T15:14:55.073 回答