我有一个视图,其中可以有大量项目供用户滚动浏览,我想实现无限滚动以启用内容的渐进式加载。
看起来有些人已经完成了分页,但谷歌并没有提出任何人讨论他们如何使用 Ember/Ember Data 完成无限列表。任何人都已经解决了这个问题并有一篇博客文章/示例代码可以分享?
我有一个视图,其中可以有大量项目供用户滚动浏览,我想实现无限滚动以启用内容的渐进式加载。
看起来有些人已经完成了分页,但谷歌并没有提出任何人讨论他们如何使用 Ember/Ember Data 完成无限列表。任何人都已经解决了这个问题并有一篇博客文章/示例代码可以分享?
GitHub Dashboard
我已经在项目中实现了无限滚动机制,我目前正在开发中。该功能在提交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.ListView 组件吗?
https://github.com/emberjs/list-view
它是在二月份的旧金山 Ember 聚会上宣布的。下面是来自 Ember Core 开发人员之一的 Erik Bryn 关于使用它的幻灯片:
我正在根据@pangratz 的工作为 Ember 编写一个无限分页插件。
如果您有任何问题或需要改进,请在那里提出任何问题。
我建议使用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 部分。
注意:
自 Ember 2.0 稳定版起,使用 (@commadelimited's answer) 和使用ListView
(@pangratz's answer) 的视图ArrayController
均已弃用/删除。