`需要'不等待在渲染模板之前返回数据 [英] `needs` not waiting for data to be returned before rendering template
问题描述
我正在尝试实施控制器需要另一个( CampaignsNew
需要 AppsIndex
),看起来像
I am trying to implement a controller needing another (CampaignsNew
needing AppsIndex
), which looks like
App.CampaignsNewController = Ember.Controller.extend({
needs: ['appsIndex']
});
在我的 CampaignsNew
模板中我正在展示它通过
And in my CampaignsNew
template I am showing it via
{{#if controllers.appsIndex.content.isUpdating}}
{{view App.SpinnerView}}
{{else}}
{{#each controllers.appsIndex.content}}
{{name}}
{{/each}}
{{/if}}
但是 controllers.appsIndex.content.isUpdating
不是真的。即它尝试在加载数据之前显示数据。
However controllers.appsIndex.content.isUpdating
is never true. I.e. it attempts to show the data before it has been loaded.
我的 AppsIndex
路由模型被覆盖: p>
My AppsIndex
route has the model overridden:
App.AppsIndexRoute = Ember.Route.extend({
model: function(controller) {
var store = this.get('store').findAll('app');
}
...
});
如果我将相同的代码放在我的 CampaignsNew中,我可以让它工作
路由,并通过 controller.content
将模板修改为每个
。对我来说,需要
不使用路由?如果我去 / apps
页面,它也可以加载数据,然后导航到 / campaigns / new
页面。
I can get it to work if I put the same code within my CampaignsNew
route and modify the template to each
through controller.content
. Which says to me that needs
is not using the route? It also works if I go to the /apps
page and it loads the data, and then navigate to the /campaigns/new
page.
如何让这个工作?谢谢!
How do I get this to work? Thanks!
编辑:
根据要求,路由器的相关部分:
As requested, the relevant parts of my router:
App.Router.map(function() {
this.resource('apps', function() {
...
});
this.resource('campaigns', function() {
this.route('new');
});
});
而 AppsIndex
以 / apps
和 CampaignsNew
在 / campaigns / new
Edit2:
在执行@ kingpin2k的建议之后,我发现Ember发出错误。以下是更新的文件和收到的错误。
After implementing the suggestion by @kingpin2k, I've found that Ember is throwing an error. Below are the updated files and the error received.
App.CampaignsNewController = Ember.ObjectController.extend({
pageTitle: 'New Campaign'
});
App.CampaignsNewRoute = Ember.Route.extend({
model: function(controller) {
return Ember.RSVP.hash({
campaign: this.store.createRecord('campaign'),
apps: this.store.find('app')
});
// return this.store.createRecord('campaign');
},
setupController: function(controller, model){
controller.set('apps', model.apps);
this._super(controller, model.campaign);
}
});
Ember抛出此错误:
Ember throws this error:
Error while loading route: Error: Assertion Failed: Cannot delegate set('apps', <DS.RecordArray:ember689>) to the 'content' property of object proxy <App.CampaignsNewController:ember756>: its 'content' is undefined.
我在线阅读,这是因为内容对象不存在。如果我设置如下:
I read online that this is because the content object doesn't exist. If I set it like so:
App.CampaignsNewController = Ember.ObjectController.extend({
content: Ember.Object.create(),
...
});
然后页面加载没有错误,当检查Ember Chrome扩展时,我可以看到数据有加载。但它不显示在页面上。我认为发生的是因为内容
对象存在,所以Ember在渲染模板之前没有等待模型的承诺来实现。似乎很奇怪,你应该以这样的方式定义内容。关于如何处理这个问题的任何见解?
Then the page loads without error, and when inspecting the Ember Chrome extension, I can see the data has loaded. But it doesn't show on the page. Which I suppose happened because the content
object existed and so Ember didn't wait for the model's promise to fulfill before rendering the template. Seems odd that you should have to define content in such a way though. Any insight on how to handle this?
Edit3:在另一个线程
推荐答案
根据您的路由器, apps
不是 campaign / new
的父级。
Based on your router, apps
isn't a parent of campaigns/new
.
这意味着有人可以点击#/ campaigns / new
,而Ember将会点击 ApplicationRoute
, CampaignsRoute
和 CampaignsNewRoute
填写所请求的URL所需的信息。使用需求作为控制器之间的沟通方式真正只有在祖传模式(也就是与你的父母,祖父母等沟通)中才有意义。
This means someone could hit #/campaigns/new
and Ember would hit ApplicationRoute
, CampaignsRoute
, and CampaignsNewRoute
to populate the necessary information for the url requested. Using needs as a way of communicating between controllers really only makes sense in an ancestral pattern (aka communicating with your parents, grandparents etc).
正如另一个简短的说明, code> AppsIndex 是 Apps
的路由,当您的网址包含一个小孩时,它不会被打。例如
Just as another quick note, AppsIndex
is a route of Apps
, it won't be hit when your url includes a child. e.g.
this.resource('apps', function() {
this.resource('chocolate', function(){
.....
});
});
URL被击中
Url being hit
#/apps/chocolate
将被击中的路线
Routes that will be hit
ApplicationRoute
AppsRoute
ChocolateRoute
ChocolateIndexRoute
只有当您未指定资源的路由时,才会触发索引路由,并且您正在击中该资源(也称为该资源)。
The index route is only hit when you don't specify a route of a resource, and you are hitting that exact resource (aka nothing past that resource).
您可以从特定的钩子返回多个模型:
You can return multiple models from a particular hook:
App.FooRoute = Em.Route.extend({
model: function(){
return Em.RSVP.hash({
cows: this.store.find('cows'),
dogs: this.store.find('dogs')
});
}
});
如果您希望主模型仍然是牛,您可以将其更改为 setupController
级别。
If you want the main model to still be cows, you could switch this up at the setupController
level.
App.FooRoute = Em.Route.extend({
model: function(){
return Em.RSVP.hash({
cows: this.store.find('cows'),
dogs: this.store.find('dogs')
});
},
setupController: function(controller, model){
controller.set('dogs', model.dogs); // there is a property on the controller called dogs with the dogs
this._super(controller, model.cows); // the model backing the controller is cows
}
});
查看第二个答案, EmberJS:如何在同一路径上加载多个模型?(第一个也是正确的,只是没有提到
Check out the second answer here, EmberJS: How to load multiple models on the same route? (the first is correct as well, just doesn't mention the gotchas of returning multiple models from the model hook).
您还可以在 setupController
中设置属性,虽然这意味着页面加载后不可用,但后来异步。
You can also just set the property during the setupController
, though this means it won't be available when the page has loaded, but asynchronously later.
使用控制器,如果你不会用模型返回你的控制器。
Use Controller if you aren't going to back your controller with a model.
App.FooRoute = Em.Route.extend({
model: function(){
return undefined;
}
});
使用ObjectController,如果要将控制器的模型设置为某个东西,那不是一个集合。
Use ObjectController, if you are going to set the model of the controller as something, that isn't a collection.
App.FooRoute = Em.Route.extend({
model: function(){
return Em.RSVP.hash({
cows: this.store.find('cows'),
dogs: this.store.find('dogs')
});
}
});
如果某件事将成为某种类型的集合,请使用ArrayController。
Use ArrayController if that something is going to be a collection of some sort.
App.FooRoute = Em.Route.extend({
model: function(){
return ['asdf','fdsasfd'];
}
});
注意
如果您重写setupController ,它不会设置控制器的模型,除非你明确地告诉它,或使用 this._super
。
App.FooRoute = Em.Route.extend({
model: function(){
return Em.RSVP.hash({
cows: this.store.find('cows'),
dogs: this.store.find('dogs')
});
},
setupController: function(controller, model){
controller.set('cows', model.cows);
controller.set('dogs', model.dogs);
// uh oh, model isn't set on the controller, it should just be Controller
// or you should define one of them as the model
// controller.set('model', model.cows); or
// this._super(controller, model.cows); this does the default setupController method
// in this particular case, ArrayController
}
});
这篇关于`需要'不等待在渲染模板之前返回数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!