无限滚动与ember.js(延迟加载)
我有一个视图,可以有大量的项目供用户滚动浏览,我想实现无限滚动以启用逐步加载的内容。
看起来有些人已经完成了分页,但Google并没有提出任何人讨论他们如何使用Ember / Ember Data完成无限列表。 任何人已经通过这个工作,并有一个博客文章/示例代码分享?
你是否知道新发布的Ember.ListView组件?
https://github.com/emberjs/list-view
它在二月旧金山Ember Meetup上宣布。 这是Erik Bryn的一个幻灯片,Ember Core的开发者之一就是使用它:
我在GitHub Dashboard
项目中实现了一个无限的滚动机制,目前我正在开发。 该function添加在提交68d1728 。
基本的想法是有一个LoadMoreView
,每当在当前视口上可见视图时,在控制器上调用loadMore
方法。 我正在使用这个jQuery插件。 它允许你注册一个inview
事件,当指定select器的元素在屏幕上可见并且消失时触发。
控制器还具有属性,用于指示是否有更多项目要加载,以及是否有当前项目被提取。 这些属性被称为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
函数的结果,所以当新模型加载到商店时(由于控制器的loadMore
中的findQuery
方法), content
被更新。 另外,在调用filter
时添加query
哈希。 这确保了对服务器的初始查询。
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; });
基于@ pangratz的工作,我正在为Ember写一个无限的分页插件 。
如果您有任何疑问或改进,请在此解答。
我会build议使用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}}
组件变得可见时,它会向你的路由发送一个动作,所以它知道用新的(获取的)logging更新模型数组。
第一个请求将被发送到:
/products?per_page=12&page=1
所以你也需要准备你的后端API来处理这些查询参数。 这显然是可定制的,请参阅自述文件的“高级用法”部分 。
注意 :
使用ListView
(@ commadelimited的答案)和视图与ArrayController(@ pangratz的答案)已被弃用/删除作为稳定版本的Ember 2.0。