我已经在GitHub Dashboard project 实现了无限滚动机制,我目前正在开发中。该功能在提交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 会在新模型加载到商店时更新(这是由于@ 987654341@ 方法在控制器的loadMore 中)。此外,在调用 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;
});