Reputation: 511
I am new to Ember, so my approach can be incorrect. I am using latest Ember 2.9.1
My plan is to update route's model and cause all components to render newly added/saved item in a collection.
(I want to update my route's model (userRoles array) with a new record of userRole after I have call save (on createRecord)).
So far I have a route that has a model like this:
model(){
// this is my "user.edit" route
let user = this.modelFor('user');
let newUserRole = this.get('store').createRecord('userRole');
newUserRole.set('user_id', user.get('id'));
return RSVP.hash({
user: user,
userRoles: store.query('userRole', { user_id: user.get('id') }),
roles: store.findAll('role'),
newUserRole: newUserRole
});
}
I then have a controller and couple of components that modify newUserRole. In a route I have an action for saving new user role:
actions: {
saveNewUserRole: function () {
let currentModel = this.modelFor('user.edit');
currentModel.newUserRole.save().then(function (newUserRole) {
currentModel.userRoles.addObject(newUserRole);
});
}
}
What's interesting is that a new item (newUserRole) gets added to a collection, but in console logging of model tells me that the new object is kind of different from other objects in the collection. Looking through similar issues for ember I find that people use: _internalModel or toArray(): here and here or services (?) for storing/updating data.
(also changed from using pushObject to addObject (v1.3+); plus observers listening for userRoles changes don't get triggered inside of components, or if I call toArray() I get 'Invalid value used as weak map key' error)
Question: What is the correct/Ember way to update my route's model with new item and cause to re-render my template. If I should use services for data, should service keep all items in a toArray()
or POJOs?
Upvotes: 1
Views: 469
Reputation: 18240
ember-data
will do most of the ugly relationship work for you automatically.
So for example you should never do something like this:
newUserRole.set('user_id', user.get('id'));
but always this:
newUserRole.set('user', user);
On a .save()
ember-data
is smart enough to save the id.
Also this looks a bit like you'r trying to load all userRole
s for a given user:
store.query('userRole', { user_id: user.get('id') }),
You should only use query
when necessary. To fetch a relationship just access the relationship:
user.get('roles'),
Assumed you have roles: hasMany('userRole')
in your models/user-role.js
.
Next with currentModel.userRoles.addObject
you modify a result array of ember data. You should only do this if you want to change the relationship. ember-data
will automatically keep your relationships in sync.
So after you've set the user
on the userRole
, the new role will be automatically in the live-array returned by user.get('roles')
. So actually you should never modify the array returned by a .query()
.
So basically this could be your model
hook:
// this is my "user.edit" route
let user = this.modelFor('user');
let newUserRole = this.get('store').createRecord('userRole', {
user
});
return RSVP.hash({
user,
userRoles: user.get('roles'),
roles: store.findAll('role'),
newUserRole,
});
And this could be your save-action:
actions: {
saveNewUserRole: function () {
let currentModel = this.modelFor('user.edit');
currentModel.newUserRole.save();
}
}
However if you only want to show the new role after you've saved it you probably should filter on isNew=false
when viewing them. User a computer property like userRolesFiltere: Ember.computed.filterBy('model.userRoles', 'isNew', false)
or a {{#unless role.isNew}}
for that.
Upvotes: 1