`需要'不等待在渲染模板之前返回数据 [英] `needs` not waiting for data to be returned before rendering template

查看:77
本文介绍了`需要'不等待在渲染模板之前返回数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施控制器需要另一个( 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆