I've waded through a lot of pages/questions regarding pagination/infinite scrolling/load more content.
Either the content is pre-loaded completely in the store or the examples requesting new data simply don't work.
I've got a blog displaying 5 posts then a 'load more' button. Upon hitting this button I'd like to request 5 more posts from the server and add them live to the page.
this.store.find('post', {limit: 5, offset: 5, sort:'createdAt desc'});
Please can you provide a working example or instructions to make it work?
EDIT: the following seems to be a good option but I don't know how to make it work
Make the model a standard array and use the route hooks and "load more" actions to fill it with records from ED query results
EDIT2 this is how I set the model for the route:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('post', { isPublished: true,
limit: 5,
sort:'createdAt desc'});
}
});
I've created a simple app for you on GitHub:
https://github.com/andrusieczko/ember-loadMore-example
Just fetch it, install dependencies and you're ready to go:
$ git clone https://github.com/andrusieczko/ember-loadMore-example.git
$ cd ember-loadMore-example
$ npm install
$ bower install # possibly you don't have to do that
$ npm start
and go to http://localhost:4200
where you have a link to #/post
route.
I've presented how you can do loadMore
button but I set up the offset
variable as well, so you can easily transform this code to the pagination.
So, in my routes/post.js
file I've got two query params defined (though in this example I'm actually using only limit
):
export default Ember.Route.extend({
queryParams: {
limit: {
refreshModel: true
},
offset: {
refreshModel: true
}
},
model: function(params) {
return this.store.find('post', {
limit: params.limit,
offset: params.offset
});
}
});
That sets up both of the query params. refreshModel: true
causes fetching new data from server (model
hook is called) whenever a query param is changed.
To have it working, you have to also define your query params in the controller (controllers/post.js
):
export default Ember.Controller.extend({
queryParams: ['limit', 'offset'],
limit: 20,
offset: 0,
pageSize: 20,
actions: {
loadMore: function() {
this.set('limit', this.get('limit') + this.get('pageSize'));
}
}
});
And the loadMore
action is just adding the pageSize
to existing limit
.
The template (templates/post.hbs
) look like that:
<h1>Posts</h1>
<ul>
{{#each post in model}}
<li>{{post.id}}. {{post.name}}</li>
{{/each}}
</ul>
<button {{action 'loadMore'}}>Load more</button>
To have the fully working example, I've created a simple server side that can understand limit
and offset
:
app.get('/api/posts', function(req, res) {
var limit = parseInt(req.query.limit);
var offset = parseInt(req.query.offset) || 0;
var filteredItems = items;
if (limit) {
filteredItems = items.slice(offset, (offset+limit));
} else {
filteredItems = items.slice(offset);
}
res.send({
post: filteredItems
});
});
where items
is an 100-elements array of [{id: 0, name: 'post0'},{id: 1, name: 'post1'},...
.
Hence the model
structure (models/post.js
):
export default DS.Model.extend({
name: DS.attr('string')
});
I hope that it will help you to understand how to implement the solution in your project.
Enjoy!