如何正确拆分控制器模型?

时间:2014-12-31 05:26:50

标签: javascript ember.js

我正在使用网络应用程序自学Ember,我已经走进了一个大问题:

页面在尝试获取json时停止,我的IndexRoute和IndexController感觉非常臃肿。此外,this.store.find('pokemon')使用RESTAdapater,并且可以将页面从呈现任何内容(除了加载器)冻结长达1.5秒。

App.IndexRoute = Ember.Route.extend({
    model: function() {

            var store = this.store;
            return Ember.RSVP.hash({
            pokeballs: App.Pokeball.all(),
            pokemon: store.find('pokemon'),
            status: App.Status.all(),
            levels: App.Levels
        });
    }
});

更新的问题:就像现在一样,我的IndexController是larger than I would like,并且充当了pokeballs和pokemon集合的中介。我认为拆分IndexController是个好主意,这样我就有了一个IndexController,一个PokemonListController和一个PokeballListController。我遇到的问题是:

  1. 如果我在' /'上映射到IndexRoute,我应该如何填充PokemonListController和PokeballListController的内容?
  2. 这实际上是一个好主意,我是否以对待他们的方式处理控制器?
  3. Webapp演示:http://theirondeveloper.github.io/pokemon-catch-rate

    Github:https://github.com/TheIronDeveloper/pokemon-catch-rate

3 个答案:

答案 0 :(得分:2)

一方面,你没有绑定路线中的单个控制器,通常只有一个控制器与一条路线相关联,但如果你需要它们,你可以随时设置更多的控制器,记住它们是模型的装饰器

 App.IndexRoute = Ember.Route.extend({
     model: function() {
        return store.find('pokemon');
    },
    setupController: function(controller, model) {
      var pokemonListController = this.controllerFor('pokemons');
      var pokeballListController = this.controllerFor('pokeball');


      controller.set('model', model); //this would be the index controller

      pokemonListController.set('model', model.pokemon);
      pokeballListController.set('model', model.pokeballs);
    }
 });

如果需要,您也可以在不等待回复的情况下呈现您的页面,一旦收到回复,Ember将处理更新您的UI。如果您的响应太慢,用户将看到该页面和一个空列表(在这种情况下,是空口袋列表的口袋妖怪),然后一旦请求得到解决,列表就会填满它。

要做到这一点,只需从模型钩子返回一个空数组,并将其更新为async:

App.IndexRoute = Ember.Route.extend({
    model: function() {
      var pokemon = [];
      var store = this.store;

      store.find('pokemon').then(function(allPokemon) {
        pokemon = allPokemon; //untested, you may need to push them instead
      });

      return Ember.RSVP.hash({
        pokeballs: App.Pokeball.all(),
        pokemon: pokemon,
        status: App.Status.all(),
        levels: App.Levels
      });
    }
});

答案 1 :(得分:1)

  1. 没有看到关于IndexRouteIndexController的任何“膨胀”。确实,许多Ember应用程序将具有多个路由,因此具有多个控制器,但是当切换到其他路由时,会发生这种情况。如果它对你的应用程序没有意义 - 那么你拥有的就是伟大的。
  2. 如果您有多条路线(以及多个控制器),@ Asgaroth建议的方法可以很好地设置多个控制器。否则,如果您只有一条路线 - 实际上不需要多个控制器。
  3. 您的数据被提取并需要一些时间这一事实是正常的。现在,理想情况下(数据提取)应该只发生一次,然后您的数据将被缓存,当您仔细阅读其他路径(您目前没有)时,您的数据已经可供您使用而不会受到任何额外的惩罚。

  4. 如果您确实需要多个控制器并且想知道如何在它们之间进行通信,那么您可能正在寻找needs API概述here

  5. <强>更新

    我又看了一眼model钩子, 很奇怪,4个中有3个东西根本没有承诺,看起来不像它们属于那里。

    所以,这是你如何清理它。

    App.IndexRoute = Ember.Route.extend({
      model: function() {
        return this.store.find('pokemon');
      }
    });
    

    这是唯一属于那里的东西。其他属性也可能是控制器上的属性,如:

    App.IndexController = Ember.Controller.extend({
      levels: function(){
        return App.Levels; 
      }.property(),
      pokeballs: function(){
        return App.Pokeball.all()
      }.property(),
      status: function(){
        return App.Status.all();
      }.property(),
    

    当然,您需要在模板和其他代码中更改对这些属性的引用。因此,举例来说,您可以从model.pokeballs更改为pokeballs。您也可以从model.pokemon更改为model

    我提交了拉取请求,告诉您我这样做的方式 - 请参阅here

答案 2 :(得分:0)

不是一个完整的答案,而是揭示路线和控制器之间的魔力......这里是模型如何被丢弃到控制器实例中

App.IndexRoute = Ember.Route.extend({
    model: function() {
        return store.fin('pokemon');
    },
    setupController: function(controller, model) {
        //the model that gets returned from the above method is added to the controller instance for you in this generated method on the route
        controller.set('model', model); //also alias'd as content in older versions of ember
    }
});