A quick answer became a very long post, hope it comes up being useful.
tl;dr: Ember’s store reuses data if it’s already in it, don’t worry too much about using RSVP.hash()
. Sometimes you might want to use this.store.find()
somewhere else that isn’t a route. And finally, look at the ApplicationRoute
and outlet
s.
It really shouldn’t be a problem for you to use RSVP.hash();
. Since you are using Ember Data, once you have the data in the store, it will use it and won’t try to call the server again unless you are using queries.
What I mean for this is:
return this.store.find('user', 1)
Will make an AJAX request the first time you call it. Then, if you use it again in the app by either coming back to the route or calling it inside some other route/controller, it won’t make an AJAX request, it will know that it’s in your Ember store and continue right away.
Don’t worry too much about using RSVP.hash()
.
Pagination on the other hand usually requires to use a query like this:
return this.store.find('user', { offset: 100, limit: 10 })
Those always make an AJAX request, and that’s probably what you want most of the time you want to paginate. If you don’t and have all your data in the store already; you can use all
.
var users = this.store.all('user');
return users.slice(100, 110);
all
is synchronous and returns an array like object, in which you can use all the array functions.
Also, if you feel like you don’t need to load all your data at once in the route and want to load the page right away and then show individual loading icons for things in your page. It’s probably worth looking at setupController()
or run your promises inside the controller / component.
setupController: function(controller, model) {
this._super.apply(this, arguments);
this.store.find('user', 1).then(function(u) {
controller.set('user', u);
});
this.store.find('posts', { offset: 100, limit: 10 }).then(function(p) {
controller.set('posts', p);
});
}
That will load your template immediately in which you can show a loading icon if user
or posts
are empty. Then, display the data once they are available.
Once more, sometimes you don’t need to use a route or don’t want a URL to paginate your data; then can call this.store.find();
inside your controller. That’s perfectly fine, or even inside a component. I usually prefer to use a route
to make all AJAX requests, but there will be ocassions when you will be forced to do it in a controller or component and that’s ok.
One more thing, if this is data that have nothing to do with the route itself, like header information or a persistent sidebar in your app. You probably want to handle those in your ApplicationRoute instead and use outlet
to render this data.