无限滚动与ember.js(延迟加载)

时间:2012-08-10 18:15:51

标签: ember.js lazy-loading infinite-scroll ember-data

我有一个视图,其中可以有大量项目供用户滚动,我想实现无限滚动以启用内容的渐进加载。

看起来像是一些人have done pagination,但谷歌没有提出任何讨论他们如何使用Ember / Ember Data完成无限列表的人。任何人都已经完成了这个并有一个博客文章/示例代码来分享?

4 个答案:

答案 0 :(得分:61)

我在GitHub Dashboard project实现了无限滚动机制,我正在开发中。该功能已添加到提交68d1728

基本思想是让LoadMoreView每当视图在当前视口上可见时在控制器上调用loadMore方法。我正在使用jQuery插件inview。它允许您注册inview事件,当指定选择器的元素在屏幕上可见并且消失时,会触发该事件。

控制器还具有属性,用于指示是否有更多要加载的项目以及是否有当前提取的项目。这些属性称为canLoadMoreisLoading

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

答案 1 :(得分:15)

您是否了解新发布的Ember.ListView组件?

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

2月旧金山Ember Meetup宣布了这一消息。这是来自Ember Bryn的幻灯片,Erik Bryn是Ember Core开发人员之一,使用它:

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

答案 2 :(得分:5)

我正根据@ pangratz的作品撰写infinite pagination plugin for Ember

如果您有任何疑问或改进,请在那里解决任何问题。

答案 3 :(得分: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来处理这些查询参数。它显然可以自定义,请看Advanced Usage section of Readme

注意

使用ListView(@ commadelimited&#39; s回答)和ArrayController的视图(@ pangratz&#39;答案)都被弃用/删除,因为Ember 2.0是稳定版本。