Do you have any good solutions for emberjs pagination and loadmore functionality
Iāve seen several different implementations of āLoad Moreā with Ember.js - @bantic has a good example of this on github https://github.com/bantic/ember-infinite-scroll
I tried these example but Itās not working with emberjs 1.4 and emberdata 1
also I need a solution to work with real sever not a fake one
The JSBin example is outdated. It is using events object instead of actions object. I updated the JSBin example with Ember.js v1.4.0 and it works as expected with a few minor tweaks.
If you are still having issues, put together a JSBin example of what youāre trying to do that isnāt working and I can take a look.
the problem is with loading data from the server in my profilesRoute Remon.ProfilesRoute=Ember.Route.extend({
model: function(){
return this.store.findQuery("profile", {
page:1
});
//rest of code...
});
I have rails pagination on server back-end I want to append new data with page increase and push for example when I click load more I want to append the new data retrieved from page2 and so on
I have a super simple āload moreā mixin I use with my posts route for my blog app (pixelhandler.com)
The RecordChunksMixin code is here: https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js
Here is the route (index) that uses the mixin: https://github.com/pixelhandler/blog/blob/master/client/app/routes/index_route.js#L5-L13
Here is a simple integration test for that feature on my blog app: https://github.com/pixelhandler/blog/blob/master/client/tests/integration/index_test.js#L18-L33
pagination in your blog is what exactly what I want ,but I am getting that error when I implemented your ixin in my application
Uncaught TypeError: Object [object Object] has no method ārefreshā
refresh
is a method of a route instance, Route - 4.6 - Ember API Documentation
i changed the code to work with pagination by page but it still throwing the same error
App.RecordChunksMixin = Ember.Mixin.create({
resourceName: null,
page: 1,
beforeModel: function () {
this.set('page', this.get('page'));
} ,
model: function () {
var query = { page: this.get('page') };
return this.store.findQuery(this.get('resourceName'), {
page: this.get('page')
});
},
afterModel: function (collection) {
this.set('meta', this.store.metadataFor(this.get('resourceName')));
var loaded = this.get('loadedIds');
collection.mapBy('id').forEach(function (id) {
loaded.push(id);
});
this.set('loadedIds', loaded.uniq());
return collection;
},
meta: null,
loadedIds: [],
setupController: function (controller) {
var collection = [];
this.get('loadedIds').forEach(function (id) {
var model = this.store.getById(this.get('resourceName'), id);
if (model) {
collection.push(model);
}
}.bind(this));
controller.set('hasMore', this.get('hasMore'));
this._super(controller, collection);
},
hasMore: function () {
return this.get('loadedIds').length < this.get('meta.total');
}.property('meta.total').volatile()
});
and my profiles_route
App.ProfilesRoute=Ember.Route.extend(App.RecordChunksMixin, {
resourceName: 'profile',
actions: {
showMore: function () {
this.refresh();
}
}
});
when I click load more link
Uncaught TypeError: Object [object Object] has no method 'refresh'
the problem was that refresh method is in version 1.4 not in 1.3 after upgrading to 1.4 and clicking show more
Uncaught Error: Assertion Failed: TypeError: Cannot read property 'container' of undefined
@Remon_Amin here is the template Iām using for the button https://github.com/pixelhandler/blog/blob/master/client/app/templates/has-more-button.hbs it just sends an action that is responded to on the router. I changed my index controller to also respond to the action https://github.com/pixelhandler/blog/blob/master/client/app/controllers/index_controller.js but return true to bubble up to route here https://github.com/pixelhandler/blog/blob/master/client/app/routes/index_route.js And the mixin here https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js
The result is that when user clicks āshow moreā a request is make like: /posts?offset=5&limit=5 then when clicked again /posts?offset=10&limit=5 each time the routeās afterModel hook is called the loadedIds
property is populated so the setupController method can use store.getById and give each loaded records to the controller.
The bower file shows what versions Iām using: https://github.com/pixelhandler/blog/blob/master/client/bower.json
Iām not sure why you get the error about the container
I didnāt reference that at all. I know the code works in production, so it sounds like youāre getting close.
@pixelhandler, in my application I have an initial list of profiles comes from the rails server
model: function(){
return this.store.findQuery("profile", {
page:1
});
}
I have a metadata of total pages and the current page what I need is that when you click load more a request send to /api/profiles?page=2 and append the results to the model ,and so on till reached the current_page === total number of pages
@Remon_Amin the flag I use to know if the show more button can be used compares the count of ids to the meta.total see: https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js#L56-L58 which is based on the JSON payload sent from the server
"meta": {
"offset": 0,
"limit": 5,
"sortBy": "date",
"order": "desc",
"total": 62
},
I based the meta info on Handling Metadata - Ember Data - Ember Guides this is where the afterModel hook gets the meta data: https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js#L29
I implement a solution ,it work great and I will do some modifications for still loading and error
Remon.ProfilesRoute=Ember.Route.extend( {
beforeModel: function(){
this.controllerFor("profiles").set("no_more",null);
this.controllerFor("profiles").set("current_page",1);
},
model: function(){
return this.store.findQuery("profile", {
page:1
});
},
actions: {
showMore: function () {
items = Em.A(),
firstpage = this.controllerFor("profiles").get("current_page"),
newpage =firstpage +1,
total =this.controllerFor("profiles").get("total_pages");
$.ajax({
url: 'http://localhost:3001/api/profiles.json?page='+newpage,
async: false,
success: function(data){
items =data.profiles;
}
});
this.modelFor("profiles").pushObjects(items);
this.controllerFor("profiles").set("current_page",newpage);
if (newpage== total){
this.controllerFor("profiles").set("no_more",true);
}
}
}
});
and in my controller
Remon.ProfilesController =Ember.ArrayController.extend({
current_page :1,
no_more: null,
total_pages : function(){
return this.store.metadataFor("profile").total;
}.property()
});
in profiles.hbs
{{#if no_more}}
<p>
no more profiles
</p>
{{else}}
<a href='#' {{action 'showMore'}}>Load more data (manually)</a>
{{/if}}