6

ビューのストリーミング ページネーション リストを作成しています。空のコレクションでアプリを開始し、定期的にアイテムをコレクションに追加します。コレクションのサイズが page_size 属性を渡すと、残りのモデルはレンダリングされませんが、compositeView はクリックするページ番号を追加する必要があります。

次のようなモデルのリストを返す関数をコレクションに含めることで、現在のページ番号とページ サイズに基づいてアイテムのみをレンダリングする、compositeView のレンダリング関数を作成することを計画しています。

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 の複合ビューを使用する必要がありますか? マリオネットの collectionView のほとんどの機能を上書きして、必要なものを取得しているようです。

コレクション内のアイテムの数が変わるたびに、2 つのことを更新する必要があります。

  • コレクション ビューの itemViews
  • 複合ビューの下部にあるページ番号
4

2 に答える 2

3

ビューレイヤーでこれを行わないことを強くお勧めします。ビューに大量のコードを追加すると、このコードの多くが複数のビュー間で複製されることになります(1つはデータの表示用、1つはページリストとカウント用、もう1つは... )。

代わりに、デコレータパターンを使用して、これを処理する方法を知っているコレクションを作成します。これは、データのフィルタリング、並べ替え、ページングのために行いますが、非常にうまく機能します。

たとえば、フィルタリングを設定する方法は次のとおりです(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便利なミックスインのセットを作成しました( https://github.com/g00fy-/marionette.generic/ )

Backbone コレクションをページ分割 + PrefetchMixin できる PaginatedMixin を使用できるため、プリフェッチされたコレクションをビューに渡す必要はありません。

あなたがしなければならない唯一のコードは次のとおりです。

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 に答える