问题
I am trying to make a request from the store for a model based on the result of a previous model request. Please find the code below:
For the route:
model(params) {
var id = params.framework_id;
var main = this;
return Ember.RSVP.hash({
question: this.store.query('question', {orderBy: 'framework', equalTo: id}),
framework: this.store.find('frameworks', id),
frameworks: this.store.findAll('frameworks')
})
}
Then in the route there is a setupController:
setupController: function(controller, model) {
this._super(controller, model);
var main = this;
...
controller.set("frameworkName", model.framework.get('name'));
var includedFramework = model.framework.get('includedFramework');
var includedFrameworkModel = this.store.find('frameworks', includedFramework);
Ember.Logger.info(model.framework)
Ember.Logger.info(includedFrameworkModel);
if (model.framework.get('includedFramework') != undefined) {
var linked = main.store.find("frameworks", model.framework.get('includedFramework'));
controller.set("linkedFramework", {id: linked.get('id'), name: linked.get('name')});
}
}
In the controller setup, using model.framework.get('name')
works without a problem. mode.framework.get('includedFramework')
works fine and returns an ID to another framework that is stored in the framework model. I then intend to pull the "included framework" in the store with another store.find
request. Unfortunately this second store.find
doesn't return the model record in the same way as the first. Here is an inspector view of what each request returns:
model.framework -
includedFrameworkModel -
Any help is greatly appreciated!
回答1:
Well, every call to ember-data that returns something that may require a request to the server, like find()
, findAll()
, query()
, save()
, and async relationships returns a PromiseObject
or a PromiseArray
.
It works the same way for objects and arrays, so just lets describe how arrays work.
A PromiseArray
is both, a Promise and a ArrayProxy.
This is very useful because you can work with it in both ways, depending on your situation.
Because the request to the server may take some time, the resulting ArrayProxy
part is often empty, and will be populated with data later. This is very useful because your handlebars template and computed properties will update when the ArrayProxy
changes.
The Promise part of the PromiseArray
will resolve as soon the data are received from the server, with an actual array, that also may update later when you do further changes on your data.
The ember router however will wait for the promise to be resolved before it loads the route, which allows you to specify a loading
substrate.
This is why model.framework
is different in setupController
. It's not the result of the .find()
but the result of the resolved promise. Thats basically what Ember.RSVP.hash
does for you.
Generally I recommend you two things.
- Don't store a model id on a model, but use a relationship.
- Don't call the store in
.setupController()
. Do all your requests in the.model()
hook and use the promise chain to do so.
Maybe take this as a inspiration:
return Ember.RSVP.hash({
question: this.store.query('question', {orderBy: 'framework', equalTo: id}),
framework: this.store.find('frameworks', id),
frameworks: this.store.findAll('frameworks')
}).then(({question, framework, frameworks}) => {
let includedFramework = framework.get('includedFramework');
let includedFrameworkModel = this.store.find('frameworks', includedFramework);
return {question, framework, frameworks, includedFrameworkModel};
});
回答2:
var includedFrameworkModel = this.store.find('frameworks', includedFramework);
The store.find() method will return the promise, the object was not resolved when you print in log.
Changed your script to something like this.
this.store.find('frameworks', includedFramework).then(function(includedFrameworkModel) {
Ember.Logger.info(includedFrameworkModel);
});
来源:https://stackoverflow.com/questions/38298989/ember-js-dynamic-model-requests