55

ユーザーがスクロールできるアイテムが多数ある可能性があるビューがあり、コンテンツのプログレッシブロードを有効にするために無限スクロールを実装したいと考えています。

一部の人々はページネーションを行ったようですが、Google は、Ember/Ember Data を使用して無限リストを作成した方法について話し合う人を見つけません。誰かがすでにこれを行っていて、共有するブログ投稿/サンプルコードを持っていますか?

4

4 に答える 4

61

I've implemented an infinite scroll mechanism at the GitHub Dashboard project, I'm currently developing. The feature is added in commit 68d1728.

The basic idea is to have a LoadMoreView which invokes the loadMore method on the controller every time the view is visible on the current viewport. I'm using the jQuery plugin inview for this. It allows you to register for an inview event, which is fired when the element of the specified selector is visible on screen and when it disappears.

The controller also has properties which indicate whether there are more items to load and if there are currently items fetched. These properties are called canLoadMore and isLoading.

The LoadMoreView basically looks like this:

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');
    });
  }
});

where the loadMore template is defined as follows:

{{#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}}

The controller which handles the fetching of more items is then implemented as follows. Note that in the loadMore method a query on the store is performed, which loads a specific page of of entries for a model.

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);
    }
  }
});

The only thing left is to initially set the content of the controller to the result of a filter function, so the content is updated when new models are loaded into the store (which happens due to the findQuery method in the loadMore of the controller). Also, a query hash is added when the filter is invoked. This ensures that an initial query to the server is made.

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;
});
于 2012-08-12T21:11:23.763 に答える
15

新しくリリースされたEmber.ListViewコンポーネントをご存知ですか?

https://github.com/emberjs/list-view

2月のサンフランシスコエンバーミートアップで発表されました。これは、EmberCore開発者の1人であるErikBrynのスライドデッキです。

http://talks.erikbryn.com/ember-list-view/

于 2013-03-13T19:26:01.690 に答える
5

@pangratzの作業に基づいて、Ember の無限ページネーション プラグインを作成しています。

質問や改善が必要な場合は、そこに問題を提起してください。

于 2013-04-02T23:13:30.613 に答える
1

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 の Advanced Usage セクションをご覧ください。

:

(@commadelimited の回答) の使用ListViewと (@pangratz の回答) を使用したビューの両方ArrayControllerは、Ember 2.0 が安定したバージョンであるため、非推奨/削除されています。

于 2015-09-27T16:52:52.770 に答える