ユーザーがスクロールできるアイテムの数が多いビューがあり、無限スクロールを実装してコンテンツのプログレッシブロードを有効にしたいと考えています。
一部の人々のように見えます ページネーションを行っています 誰もがすでにこれを行っており、ブログ投稿/サンプルコードを共有していますか?
新しくリリースされたEmber.ListViewコンポーネントを知っていましたか?
https://github.com/emberjs/list-view
2月のサンフランシスコEmber Meetupで発表されました。以下は、使用に関するEmberコア開発者の1人であるErik Brynのスライドデッキです。
GitHub Dashboard
project で無限スクロールメカニズムを実装しました。現在開発中です。この機能はcommit 68d1728 で追加されます。
基本的な考え方は、ビューが現在のビューポートに表示されるたびにコントローラーでLoadMoreView
メソッドを呼び出すloadMore
を用意することです。これにはjQueryプラグイン inview を使用しています。 inview
イベントに登録することができます。このイベントは、指定されたセレクターの要素が画面に表示され、消えたときに発生します。
コントローラには、ロードするアイテムがまだあるかどうか、および現在フェッチされているアイテムがあるかどうかを示すプロパティもあります。これらのプロパティは、canLoadMore
およびisLoading
と呼ばれます。
LoadMoreView
は基本的に次のようになります。
App.LoadMoreView = Ember.View.extend({
templateName: 'loadMore',
didInsertElement: function() {
var view = this;
this.$().bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) Ember.tryInvoke(view.get('controller'), 'loadMore');
});
}
});
ここで、loadMore
テンプレートは次のように定義されます。
{{#if isLoading}}
fetching some more stuff <img width="10" src="img/ajax-loader.gif" >
{{else}}
{{#if canLoadMore}}
<a {{action "loadMore" target="controller" }}>click to load more items</a>
{{else}}
<i>no more items</i>
{{/if}}
{{/if}}
さらに多くのアイテムのフェッチを処理するコントローラーは、次のように実装されます。 loadMore
メソッドでは、ストアのクエリが実行され、モデルのエントリの特定のページがロードされることに注意してください。
App.EventsController = Ember.ArrayController.extend({
currentPage: 1,
canLoadMore: function() {
// can we load more entries? In this example only 10 pages are possible to fetch ...
return this.get('currentPage') < 10;
}.property('currentPage'),
loadMore: function() {
if (this.get('canLoadMore')) {
this.set('isLoading', true);
var page = this.incrementProperty('currentPage');
// findQuery triggers somehing like /events?page=6 and this
// will load more models of type App.Event into the store
this.get('store').findQuery(App.Event, { page: page });
} else {
this.set('isLoading', false);
}
}
});
残っている唯一のことは、最初にコントローラーのcontent
をfilter
関数の結果に設定することです。したがって、新しいモデルがストアにロードされると、content
が更新されます(これは、コントローラーのfindQuery
のloadMore
メソッドが原因で発生します)。また、query
が呼び出されると、filter
ハッシュが追加されます。これにより、サーバーへの最初のクエリが作成されます。
App.eventsController = App.EventsController.create({
content: []
});
var events = App.store.filter(App.Event, { page: 1 }, function(data) {
// show all events; return false if a specific model - for example a specific
// type of event - shall not be included
return true;
});
私は Emberの無限のページネーションプラグイン @pangratzの仕事に基づいて書いています。
ご質問や改善点がある場合は、問題を解決してください。
Ember Infinity アドオンを使用することをお勧めします。 Ember 1.10から2.0+までをサポートしています。セットアップは比較的簡単です。テンプレート。
ルート(Product
はモデル例です):
import InfinityRoute from 'ember-infinity/mixins/route';
export default Ember.Route.extend(InfinityRoute, {
model() {
/* Load pages of the Product Model, starting from page 1, in groups of 12. */
return this.infinityModel('product', { perPage: 12, startingPage: 1 });
}
});
テンプレート:
{{#each model as |product|}}
...
{{/each}}
{{infinity-loader infinityModel=model}}
いつ {{infinity-loader}}
コンポーネントが表示されると、ルートにアクションが送信されるため、モデル配列を新しい(フェッチされた)レコードで更新することがわかります。
最初のリクエストは以下に送信されます:
/products?per_page=12&page=1
したがって、これらのクエリパラメータを処理するバックエンドAPIを準備する必要もあります。明らかにカスタマイズ可能です。 Readmeの高度な使用法セクション をご覧ください。
注:
ListView
(@commadelimitedの回答)とArrayController
(@pangratzの回答)のあるビューの両方は、Ember 2.0が安定バージョンであるため、廃止/削除されました。