基于模型属性切换控制器和路径视图的最佳方法

时间:2014-06-24 14:46:17

标签: ember.js

我需要根据模型的属性更改路径的视图和控制器。因此,例如,假设我将路由层次定义为:

Ember.Router.map(function () {
    this.resource("games", function () {
        this.resource('game', {path: ':game_id'}, function () {
            this.route('basics');
            this.route('advanced');            
        });
    });
});

我的游戏模型看起来像这样:

App.Game = DS.Model.extend({
    name: DS.attr('string'),
    category: DS.attr('string)
});

因此,如果游戏的名称是足球,我想去那个游戏的基础路线,那么我想使用footballBasicsController并使用football-basics-view。我这样做的方法是使用GameBasicsRoute中的renderTemplate挂钩,如下所示:

AS.GameBasicsRoute = Em.Route.extend({
    ......

    renderTemplate: function (controller, model) {
        var gameName = model.get("name"),
            template = gameName + "-basics",
            gameBasedController = controller;

        //if cannot resolve the template then use the default template
        template = (this.container.resolve('template:' + template)) ? template : 'game.basics';

        /**
         * first check if we have controller defined, if it is use the controller instance that is alive
         * or else create a new one
         * */
        if (this.container.lookupFactory('controller:' + gameName + "-basics")) {
            gameBasedController = this.controllerFor(gameName + '-basics');
            gameBasedController.set("model", model);
            controller.set('gameBasedController', typeBasedController);//might want to do sth with it later
        }

        this.render(template, {
            'controller': gameBasedController
        });

    },

});

这很好用,但是如果我想利用视图的didInsertElement挂钩,我会遇到一些问题。控制器也没有完全被破坏(尽管它可能是设计的) - 我之所以这么认为是因为当我从一条路线切换到另一条路线时,属性的状态会被保留。

我本可以只有一个基于模型属性切换模板的GameBasicsView,但后来我不确定如何将上下文控制器设置为默认GameBasicsController以外的视图。

我们非常感谢您的反馈意见。感谢。

1 个答案:

答案 0 :(得分:0)

游戏类型是如此截然不同,以至于他们都需要自己的控制器和视图?我个人会在模板级别而不是在控制器级别上分解。为每种游戏类型在自己的视图中包含一个部分模板,它们都可以共享同一个控制器......

也就是说,您可以使用render帮助程序,它将为您包含的每个部分模板生成一个控制器。您需要传递模型上下文,但这很简单。

http://emberjs.com/guides/templates/rendering-with-helpers/#toc_the-code-render-code-helper

所以在你的情况下,你可以做很多事情:

{{#if isFootball}}
  {{render "football" this}}
{{/if}}

{{#if isSoccer}}
  {{render "soccer" this}}
{{/if}}

isFootball可以是一个计算属性,用于检查游戏类型并返回一个布尔值。这将生成App.FootballViewApp.FootballController,以便您可以指定这些上下文中的行为。

或者,在模板中你可以绑定游戏类型(类别?),或者你可以计算格式化的字符串属性:

{{render getGameTemplate this}}

你的游戏控制器:

getGameTemplate: function () {
  return this.get('category') + "_formatted"; //You could format this template name string if needed
}.property('category')

希望有所帮助!