如何在初始路由渲染上触发子视图渲染?

时间:2014-03-20 14:52:42

标签: javascript ember.js

我知道这很容易在琐碎的情况下做,但我已经添加了改变哪个控制器和放大器的能力。子模板用于特定的{{outlet}}子视图,这使我对恢复基础知识感到困惑。

我在jsbin here上有一个有效的例子。如果您想直接跳到相关屏幕,请使用this link

问题出现在activites\new路线上。我希望视图以文本

开头
  

请选择一个模板以继续编辑活动​​。

最初渲染时。但是要显示此文本,您必须选择一个模板,然后将选择返回到提示- Select Template -

这些是完成选择更改模板渲染操作的相关对象。

// NewActivityController extends EditActivityController, so this observable 
// is re-used without being shared
App.EditActivityController = Ember.ObjectController.extend({
    activityTypeDidChange: function() {
      var selectedType = this.get('activityType');
      console.log("EditActivityController ActivityTypeDidChange: "
        + (selectedType && selectedType.get('key') || 'null'));
      this.send('changeType', selectedType);
    }.observes('model.activityType')
});

// The controller dispatches an event to trigger the action in the route
App.NewActivityRoute = App.AuthenticatedRoute.extend({
  renderTemplate: function() {
    this.render('edit_activity', {
      controller: 'new_activity'
    });
    // This doesn't work for setting the initial sub-render
    //var type = model.get('activityType');
    //if(type) {
      //this.render("Edit"+type.key, {into: 'index'});
    //} else {
      //this.render("NoActivityType", {into: 'index'});
    //}
  },
  model: function() {
    return App.Activity.create({
      title: "please enter a title",
      subjectCode: "please enter a subject code",
      activityCode: "please enter an activity code",
      activityType: null
    });
  },
  actions: {
    changeType: function(selection) {
      console.log("NewActivityRoute ChangeType called: "
        + (selection && selection.get('key') || 'null'));
      if(selection) {
        this.render("Edit"+selection.get('key'),
                    {outlet: 'edit', into: 'edit_activity'});
      } else {
        this.render("NoActivityType",
                    {outlet: 'edit', into: 'edit_activity'});
      }
    }
  }
});

正如评论所说,你无法在初始渲染中获得模型。即使仅取消注释model.get行也会导致控制器和路径之间的事件分派中断。

如果您弹出控制台,当模型EditActivityController初始化为{{{}时,您会看到ActivityTypeDidChange的{​​{1}}观察者被触发1}}。这会调度activityType事件,但它实际上会冒泡到null,因此changeType无法处理它以呈现正确的子视图。

1 个答案:

答案 0 :(得分:0)

好吧,我对Route.renderTemplate钩子有一个根本的误解。事实证明,您不能只期望在方法中定义model,您必须将其指定为参数。

  

renderTemplate控制器模型
packages/ember-routing/lib/system/route.js:1148中定义

     

您可以用来为当前路线渲染模板的钩子。

     

使用当前路径的控制器和模型钩子提供的model调用此方法。默认情况下,它会呈现路径的模板,并使用路由的controller进行配置。

为了清楚起见,在函数声明中以粗体显示的参数。将参数添加到我的renderTemplate代码钩子的工作方式与我预期的完全一样。

renderTemplate: function(controller, model) {
  this.render('edit_activity', {
    controller: 'new_activity'
  });

  var type = model.get('activityType');
  if(type) {
    this.render("Edit"+type.key,
      {outlet: 'edit', into: 'edit_activity'});
  } else {
    this.render("NoActivityType",
      {outlet: 'edit', into: 'edit_activity'});
  }
}