How to reload an asynchronous with links hasMany relationship?

Assume that

Post = DS.Model.extend({ comments: DS.hasMany({async: true}) }) Comment = DS.Model.extend({ post: DS.belongsTo() }) 

and I have to use the links function, because otherwise I get 414 error due to too many comments on the post.

Since this is commit https://github.com/emberjs/data/commit/4d717bff53f8c93bedbe74e7965a4f439882e259

It seems that it is not possible to reload post.get ('comments'), i.e. send a GET request like post / 42 / comments.

Is there any solution for this?

+12
javascript ember-data
Nov 14 '13 at 16:48
source share
6 answers

Thanks to @igorT, this is implemented. https://github.com/emberjs/data/pull/2297

ManyArray now has a reload () method that you can even call if the relation is not already loaded.

You can see some usage examples by reading tests

+7
Sep 19 '14 at 2:08
source share

UPDATE

Like @ sly7_7, in the answer below this function is now available in ember data. Therefore, if you are using version 1.0.0-beta.11 or higher, this code is not needed

You can open ManyArray again and create a new method called reloadLinks() . With the following:

 var get = Ember.get; DS.ManyArray.reopen({ reloadLinks: function() { var records = get(this, 'content'), store = get(this, 'store'), owner = get(this, 'owner'), type = get(this, 'type'), name = get(this, 'name'), resolver = Ember.RSVP.defer(); var meta = owner.constructor.metaForProperty(name); meta.type = type; var link = owner._data.links[meta.key]; store.findHasMany(owner, link, meta, resolver); } }); 

The following is used:

 comments.reloadLinks(); 

Take a look at this script http://jsfiddle.net/H6Gqf/

+15
Nov 27 '13 at 17:03
source share

Rebooting hasMany is not yet built into Ember Data, but it is on its way. The solution I'm using requires Ember Data 1.0b9 + canary, which includes refuting matching finds .

Step 1: Come in.

I chose the ApplicationAdapter level, but you can do it based on the adapter for each model. Here is what I have:

 MyApp.ApplicationAdapter = DS.ActiveModelAdapter.extend({ coalesceFindRequests: true }); 

To give you an idea of ​​why this is important and good, on one page of our application there were up to 50 requests before this change. Now we see only 11. It's still not great, but this is one of the improvements!

Step 2: Reload Records in the Association

I just complete the reboot in the function on my model as follows:

 MyApp.SomeModel = DS.Model.extend({ fooMany: DS.hasMany('foo', { async: true }), barMany: DS.hasMany('bar', { async: true }), bazOne: DS.belongsTo('baz', { async: true }), reloadAssociated: function () { var foosPromises = this.get('foos').invoke('reload'), barsPromises = this.get('bars').invoke('reload'), bazPromise = this.get('baz').reload(); return Em.RSVP.hash({ foos: foosPromises, bars: barsPromises, baz: bazPromise }); } }); 

I admit that this is not very beautiful, but this is the best solution that I came up with until rebooting was built into the associations.

+2
Jul 30 '14 at 12:44
source share

I had the same problem and I cheated to find a "solution"

i created the component "CommentLoader". This component takes one argument (post_id) and before "inserting" (willInsertElement) I will draw all the comments and make them. it works, but ... I'm not proud of it :(

+1
Nov 27 '13 at 10:26
source share

With ember-data-1.0.0-beta.10 I am using the following model extension.

Just call model.reloadRelationship(name) , where name is the name of the model attribute representing the relation.

This works for both normal and link belongs to / hasMany relationships.

 DS.Model.reopen({ reloadRelationship: function(name) { var meta = this.constructor.metaForProperty(name), link = this._data.links ? this._data.links[meta.key] : null; if (!link) { if (meta.kind === 'belongsTo') { this.get(name).then(function(model) { model.reload(); }); } else { this.get(name).invoke('reload'); } } else { meta.type = this.constructor.typeForRelationship(name); if (meta.kind === 'belongsTo') { this.store.findBelongsTo(this, link, meta); } else { this.store.findHasMany(this, link, meta); } } } }); 

The only thing missing here is some checks, for example checking if the model is already reloading, when the model is reloading a link or checking if the property name exists in the current model.

EDIT ember-data-1.0.0-beta.14:

 DS.Model.reopen({ reloadRelationship: function(key) { var record = this._relationships[key]; if (record.relationshipMeta.kind === 'belongsTo') { return this.reloadBelongsTo(key); } else { return this.reloadHasMany(key); } }, reloadHasMany: function(key) { var record = this._relationships[key]; return record.reload(); }, reloadBelongsTo: function(key) { var record = this._relationships[key]; if (record.link) { return record.fetchLink(); } else { record = this.store.getById(record.relationshipMeta.type, this._data[key]); return record.get('isEmpty') ? this.get(key) : record.reload(); } } }); 

The HasMany relationship will be returned to the built-in reload method.

For a BelongsTo relationship, first check if you need to reload the record (if it is not already loaded up to this point, it will only call to receive the record, otherwise it will cause a reboot).

+1
Sep 18 '14 at 21:35
source share

Another option is to add a method to the model. Should also work on hasMany:

 search: DS.belongsTo('search', {async: true}) updateSearch: -> resolver = Ember.RSVP.defer() resolver.resolve = => # do something after promise resolves relationship = @constructor.metaForProperty('search') link = @_data.links[relationship.key] @store.findBelongsTo this, link, relationship, resolver 
0
Dec 13 '13 at 6:37
source share



All Articles