我有一个视图,用户需要滚动查看大量内容,我想实现无限滚动以实现内容的逐步加载。
看起来有些人已经进行了分页,但谷歌上没有人讨论他们如何使用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
函数的结果,这样当新模型加载到存储器中时(由于控制器中的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;
});
return true
),所以使用filter是否还有其他好处呢? - Alexander Wallace MatchneerEmber.tryInvoke
? - Jakub Arnoldvar event = ...
。为什么要将其保存在变量中?变量在哪里使用,过滤器有什么用途? - polyclick你是否知道最近发布的Ember.ListView组件?
https://github.com/emberjs/list-view
这是在二月份旧金山 Ember Meetup 上宣布的。以下是一位 Ember 核心开发者 Erik Bryn 的演示文稿,讲解如何使用该组件:
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
li
元素的ul
),而不是从UI中删除现有内容并用您从存储中获取的内容替换它(通常是表格数据视图)。但可能涉及其他方面(如缓存等)。我想看一个例子,因为我目前没有时间亲自尝试编码。 - MilkyWayJoe