Javascript ember.js-使用可选参数和默认模型定义路线

Javascript ember.js-使用可选参数和默认模型定义路线,javascript,ember.js,Javascript,Ember.js,我想在emberjs中定义一个路由,它有一个可选参数 例如: /video 和 /video/123 如果未提供任何参数,我希望使用默认模型/装置。 如果提供了一个参数,那么我显然希望使用该参数查找模型 如果随后转到另一个管线,并返回不带参数的管线,则希望使用先前加载的模型 例如: 启动应用程序 /video-显示我的默认/设备型号 /video/123-显示123型 /另一条路线-显示新路线 /video-显示型号123 这可能吗?当然,您必须做一些有点古怪的事情,比如将最后一个视频存储在某个

我想在emberjs中定义一个路由,它有一个可选参数 例如:

/video
/video/123

如果未提供任何参数,我希望使用默认模型/装置。 如果提供了一个参数,那么我显然希望使用该参数查找模型

如果随后转到另一个管线,并返回不带参数的管线,则希望使用先前加载的模型

例如:

启动应用程序

/video
-显示我的默认/设备型号

/video/123
-显示123型

/另一条路线
-显示新路线

/video
-显示型号123


这可能吗?

当然,您必须做一些有点古怪的事情,比如将最后一个视频存储在某个全局变量中,但这取决于您


有一个干净的方法可以做到这一点,尽管它有点“棘手”。其思想是使用嵌套路由保存id,但不渲染id,而是让父路由负责使用渲染辅助对象渲染id。当您这样做时,所有逻辑都可以在VideoChoiceController中运行,并且它将用于显示默认视频或特定视频。这样做时,不需要显式地“记住”最后一个视频,路由引擎表示的状态机会为您执行此操作

App.Router.map(function) {
  this.resource('video', function(){
    this.route('choice', {path: ':video_id'});
  });
});

App.VideoRoute = Ember.Route.extend({
  model: function(params) {
    return App.get('defaultVideo');
  },

  setupController: function(controller, model) {
    var video_choice = this.controllerFor('video.choice')

    // this is necessary if you want, for example,
    // to display the name or a link to the default video
    // when a specific video is being displayed
    controller.set('model', model);

    if(Ember.isEmpty(video_choice.get('model'))){
      video_choice.set('model', model);
    }
  }
});

App.VideoChoiceRoute = Ember.Route.extend({
  model: function(params) {
    return this.get('store').find('video', params.video_id);
  },

  renderTemplate: function() {
    // if you don't override renderTemplate to do nothing, 
    // everything will still work but you will get an assertion
    // error that render should only be used once with a
    // singleton controller
  }
});



<script type="text/x-handlebars">
  <div>
    {{outlet}}
  </div>
</script>

<script type="text/x-handlebars" data-template-name='video'>
  <div> attrributes here always refer to the default video: {{name}} </div>
  {{render "video.choice"}}
</script>

<script type="text/x-handlebars" data-template-name='video'>
  <div> 
    attrributes here always refer to specific or last video, 
    or default if a specific video has never been loaded: {{name}}
  </div>
</script>
App.Router.map(函数){
此.resource('video',function(){
this.route('choice',{path:':video_id'});
});
});
App.VideoRoute=Ember.Route.extend({
型号:功能(参数){
返回App.get('defaultVideo');
},
设置控制器:功能(控制器、型号){
var video\u choice=this.controllerFor('video.choice'))
//这是必要的,例如,
//显示默认视频的名称或链接
//显示特定视频时
controller.set('model',model);
if(Ember.isEmpty(video\u choice.get('model')){
视频选择集(“模型”,模型);
}
}
});
App.VideoChoiceRoute=Ember.Route.extend({
型号:功能(参数){
返回此.get('store').find('video',params.video_id);
},
renderTemplate:function(){
//如果不重写renderTemplate以不执行任何操作,
//一切仍然有效,但您将得到一个断言
//错误:渲染只应使用一次
//单例控制器
}
});
{{outlet}}
属性在这里总是指默认的视频:{{name}
{{render“video.choice”}
这里的属性总是指特定的或最后的视频,
如果从未加载过特定视频,则为默认值:{{name}

我最终使用了不同的解决方案:

  this.resource('video', function() {
    this.route('index', {path: '/'});
    this.route('item', {path: ':id'});
  });
这些路线支持:

/video
-显示我的默认/设备型号

/video/123
-显示123型

当用户访问
/video
时,VideoIndexRoute必须重定向到没有任何id的VideoItemRoute

var VideoIndexRoute = Em.Route.extend({

  afterModel: function() {

    // this is the tricky part
    this.replaceWith('video.item', '');

  }

});
现在,VideoItemRoute必须检查是否有任何关联的模型,如果缺少该模型,则应使用默认装置或新装置

var VideoItemRoute = Em.Route.extend({

  model: function(param) {
    if (param.id) {
      return this.store.find('video', param.id);
    }
  },

  setupController: function (controller, model) {
    if (!model) {
      model = this.store.createRecord('video',{
        name: 'default Name'
      });
      // or use fixture...
    }
    this._super(controller, model);

  }

});

你漏掉了他需要做的很多事情,比如指定在
renderTemplate
中呈现哪个模板,以及处理videoModel和视频控制器之间的复制等。请审阅我的回复,感谢我之所以说这有点棘手,是因为它依赖于这样一个事实:更改路由会撕裂旧路由模板,但不会清除其控制器,我不确定这一细微差别是否有意被利用。还有另一种方法可以做到这一点,使用视频/索引路由并让视频/索引模板执行
{{render'video.choice'defaultVideo}}
。然后您可以让VideoChoiceRoute按正常方式进行渲染。这实际上可能会更好,也不会太“棘手”。请审阅我的回答,谢谢
var VideoItemRoute = Em.Route.extend({

  model: function(param) {
    if (param.id) {
      return this.store.find('video', param.id);
    }
  },

  setupController: function (controller, model) {
    if (!model) {
      model = this.store.createRecord('video',{
        name: 'default Name'
      });
      // or use fixture...
    }
    this._super(controller, model);

  }

});