I am adding a JSON API to the Ember tutorial app found here with Ember-Data. The flow of the app goes like this: Load the website: App fetches todos from the API via a GET request.Add a todo: App add a new todo via a POST requestEdit the todo that was just added: Fails because although the todo is in the database, the app doesn't know about it, because it hasn't gotten the list of todos since the todo was added. What I'm thinking I need is to refresh the list of todos every time a new one is added. I've tried to do something like this, but it only observes a property.
Just use a Live Record Array
Takes a type and filter function, and returns a live RecordArray that
remains up to date as new records are loaded into the store or created
locally.
The callback function takes a materialized record, and returns true
if the record should be included in the filter and false if it should
not.
The filter function is called once on all records for the type when
it is created, and then once on each newly loaded or created record.
If any of a record's properties change, or if it changes state, the
filter function will be invoked again to determine whether it should
still be in the array.
IE
this.store.all('post')
this.store.filter('post', function(post){ return post.get('body').indexOf('ember')>=0;});
Example:
http://emberjs.jsbin.com/OxIDiVU/22/edit
Related
I have the following route:
/projects/5/files
I read in the API that using find() and findAll() will automatically update any templates that use their results when records are pushed to the store. How can I do that with the child file records?
Take note that the file records are already in the store as they are returned embedded with the project response from the server.
Currently, this is the model hook in my projects/files.js route:
model() {
return this.modelFor('project').get('attachments')
}
This works on first load but won't update when adding records to the store afterwards.
Actually it does update!
Checkout this ember-twiddle!
You can not just add an attachment but also have to connect it to the project!
I have a data object which i have stored from the response of the first request. If I go back to the old page, how do I render the template using the cached object without sending another request.
Assuming you're using ember-data v2...
Have a look at the shouldBackgroundReloadAll and shouldBackgroundReloadRecord methods on DS.Adapter.
http://emberjs.com/api/data/classes/DS.Adapter.html#method_shouldBackgroundReloadAll
If you override these methods in your adapter class to return false, then ember-data will not re-fetch records from the server if it already has the record cached.
More information here: http://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html#toc_new-adapter-hooks-for-better-caching
If you have records that you wish to store statically across requests, you should create a service and store it there. Services are singletons, which retain state between route transitions.
When an ember route is entered with a dynamic path, ember data will load the object preloaded in the store if it exists and not make a server request. For example:
App.SomethingRoute=Ember.route.extend({
model:function(params){
this.store.find("something",params.something_id)
}
})
My app is such that I don't want to perform updating of depend models server side(I will for simple relationships but there are other I want to just pull updated records from the server). So I have been able to solve the problem by incorporating a server request in the afterModel hook:
App.SomethingRoute=Ember.route.extend({
model:function(params){
this.store.find("something",params.something_id)
},
afterModel:function(model){
$.getJSON("/somethings/"+model.id).then(function(data){
var serialized_something=route.store.serializerFor("something").normalize(TaxProgram.Something,data.something)
route.store.update("something",serialized_something)
})
})
What I can't figure out is how to check to see if the model hook is actually called, and in that case not make an additional wasteful afterModel call. I could set a property on the route that contains this information but I was hoping that Ember had a method to do this. Any suggestions?
No, there is no specific provision in Ember to handle the situation you describe.
In a similar situation I did exactly what you said you want to avoid, which is to set a property to remember if the model hook had been called. beforeModel is a useful place to initialize that property.
However, your implementation of this notion is flawed, and you're replicating too much Ember Data logic in your afterModel hook. Instead, you should simply consider using unload to remove the model instance from the local store when unnecessary and force a refresh next time you do a find on it, or do a reload at the appropriate point to force the reload.
Why the 'Todos.ApplicationAdapter = DS.FixtureAdapter.extend();' replace to '
Todos.ApplicationAdapter = DS.LSAdapter.extend({
namespace: "todos-emberjs"
});
' can be achieved local stores?
what's the meaning of 'namespace: "todos-emberjs"'?
There are how much kinds of adapters? And I should how to use them? How to define an adapter?
(Check out the picture here to see where ADAPTER component fits in)
I just went through EmberJS tutorial recently and from what I understood:
1)What are EmberJS adapters?
The adapters are objects that take care of communication between your application and a server. Whenever your application asks the store for a record that it doesn't have cached, it will ask the adapter for it. If you change a record and save it, the store will hand the record to the adapter to send the appropriate data to your server and confirm that the save was successful.
2)What types of EmberJS adapters are available?
Right now I am only aware of DS.RESTAdapter which is used by default by the store (it communicates with an HTTP server by transmitting JSON via XHR), DS.FixtureAdapter(something like in-memory storage which is not persistent) and DS.LSAdapter(something like local-storage which is persistent).
3)Why LSAdapter instead of FixtureAdapter in Todos tutorial?
FixtureAdapter stores data in-memory and thus whenever you refresh your page, the data gets reassigned to initial values. But LSAdapter is available on github which uses persistent storage to store and retrieve data, hence enabling you to retain all the changes even after you refresh your page.
4)Why namespace: "todos-emberjs"?
If your JSON API lives somewhere other than on the host root, you can set a prefix that will be added to all requests. For example, if your JSON APIs are available at /todo-emberjs/ you would want it to be used as a prefix to all the URLs that you are going to call. In that case, set namespace property to todo-emberjs.
(Hope it helps, loving EmberJS btw !)
With Ember Data, how can I test whether a model instance already exists in the local store?
Assume an Ember Data model type named App.User = DS.Model.extend({ ... }).
someUser = App.User.find(someId) may or may not issue an XHR to the remote server depending on whether a record with someId already exists in the local store. Before issuing that XHR, I'd like to first check for existence of such a record in the local store.
Use DS.Store.hasRecordForId(type, id).
While not as efficient as digging into the store's cache for a particular id, DS.Model comes with an all() method that is clean and useful in this situation. App.User.all() returns a filtered array containing all known User records, so one way to check for the existence of a record with a given id is the following:
var isLoaded = App.User.all().some(function(user) {
return user.get('id') === someId;
});