Can you preload the related data so your relationships are cached in ember-data?

I have a simple hasMany / belongsTo that looks like this:

App.Foo = DS.Model.extend({ bar: belongsTo('bar', { async: true}) }); App.Bar = DS.Model.extend({ foos: hasMany('foo', { async: true}) }); 

I have situations in the route code that cancel the request, and when the response returns, I refer to the corresponding "bar" model when I filter / etc

 this.store.all('foo').clear(); var fooz = self.store.all('foo'); //new code return this.store.find('foo').then(function(response) { var filtered = response.filter(function(foo) { return foo.get('bar').get('name') === 'bazz'; }); //other code that would normally be executed top-down //including side-effect stuff like this //self.store.createRecord('foo', someHash); return fooz; //new code }); 

The above does not work the first time since foo.get ("bar") is a promise. But this is only a problem the first time (in subsequent $ .ajax requests, it seems that there are all bar objects cached, so this is not a problem)

What is strange is that before I even downloaded the application, I already pulled out all the bar data in init (shown below). So, why does the ember data even have to resolve the promise of a โ€œbarโ€ when technically this data should already be in the store locally?

 App.initializer({ name: 'bootstrap', initialize: function() { App.deferReadiness(); var store = App.__container__.lookup("store:main"); var bars = store.find('bar'); var configurations = store.find('configuration'); Ember.RSVP.all([bars, configurations]).then(results) { App.advanceReadiness(); }); } }); 
+6
source share
1 answer

Share a few things here.

Save cache

 this.store.all('foo').clear(); 

just breaks the internal filter all until the foo record is changed / added / deleted, causing the filter to be recounted for writing to the repository. I say this to show that clear does not delete records from the ED repository.

Example (click the button, look at the console, read the funny action code)

http://emberjs.jsbin.com/OxIDiVU/103/edit

At the same time, the ajax is not cached, it is a property / relation to the record instance that is cached (and the record).

The correct way to delete records from the repository is store.unloadAll('foo')

Promiselandia

I know that you are already familiar with promises, so this part may be useless, but itโ€™s worth documenting

Asynchronous relationships are really cool because they return PromiseObject / PromiseArray for belongsTo / hasMany . PromiseObject / PromiseArray extends ObjectProxy / ArrayProxy (these are the same things as ObjectController / ArrayController ). This essentially enables PromiseObject / PromiseArray ability of the proxy to get / set the model properties under it. In this case, the installation / receipt occurs according to the promise, โ€œdoes not workโ€ until the promise is resolved (it does not work, just return undefined). * Caution, methods do not exist by promise, so you cannot name a saved promise and expect it to work.

Ex. using your models.

 var foo = this.store.find('foo', 1); var bar = foo.get('bar'); // PromiseObject bar.get('name'); // undefined 

later, the bar resolved, the bar is still a PromiseObject

 bar.get('name'); // billy 

foo will continue to return a PromiseObject

 var bar2 = foo.get('bar'); // PromiseObject bar2.get('name'); // billy 

preservation

 bar.save(); // Boom no workey bar.then(function(realBar){ realBar.save(); // workey }); 

In your case, I have 3 recommendations

Create your own promise, decide when you want, use Ember.RSVP.all in the necessary entries (given that they may or may not be allowed, therefore, async)

 var self = this; var promise = new Ember.RSVP.Promise(function(resolve, reject){ self.store.find('foo').then(function(foos) { Em.RSVP.all(foos.getEach('bar')).then(function(bars){ var filtered = bars.filterBy('name', 'bazz'); resolve(filtered); }); }); }); return promise; 

http://emberjs.jsbin.com/OxIDiVU/104/edit

asynchronous properties

Many times with asynchronous objects / properties that were not allowed during the model hook (which blocks on promises and wait for their resolution), a good trick is to set a placeholder, etc.

 var items = []; controller.set('model', items); // promise from above promise.then(function(records){ items.pushObjects(records.toArray()); // toArray may or may not apply }); 

http://emberjs.jsbin.com/OxIDiVU/106/edit

+10
source

All Articles