EmberJS:如何从控制器的操作转换到路由器

13

我有一个操作:

{{action create target="controller"}}

我已经将其定位到绑定控制器(而不是路由器),就像这样:

App.AddBoardController = Ember.Controller.extend
    create: ->
        App.store.createRecord App.Board, {title: @get "boardName"}
        App.store.commit()
        //TODO: Redirect to route

如何从控制器操作重定向回路由?

3个回答

19

在Ember控制器操作中使用transitionToRoute('route')进行重定向:

App.AddBoardController = Ember.Controller.extend({
    create: function(){ 
        ...
        //TODO: Redirect to route
        this.transitionToRoute('route_name');
    }
...

transitionToRoute seems to no more exist in Ember 3 and raises the error when using in a controller: Uncaught TypeError: Cannot read property 'transitionToRoute' of undefined - belgoros

17
事实上,这并不是Ember的惯用方式。根据我所知道的和Tom Dale本人所学到的,以下是关于该代码的一些评论:
  • 首先,你不应该从路由之外进行transitionTo:这样做会使你面临严重问题,因为你不知道路由处于哪种状态,所以为了保持运行,你将很快降低设计质量,而且整体代码质量也会下降,最终你的应用程序稳定性也会下降。
  • 其次,你正在显示的行动内容应该位于路由内部,以避免不希望的上下文执行。路由确实是强制整个应用程序具有一致行为的一种方式,其中行动仅在某些状态下被处理。虽然你将行动实现放在控制器中,但是这些行动可以在任何时候被调用,包括错误的时候...
  • 最后,Ember的控制器不旨在包含行为,它们更像是增值包装器,主要保存计算属性。如果你仍然想要因素化原语,也许模型可以是一个好地方,或者是一个第三方上下文,但绝对不是控制器。

你应该把行动放在路由内部,然后相应地转换。

希望这会有所帮助。

更新

第一个示例(接近你的示例)

在适当的路线上:

saveAndReturnSomewhere: function (router, event) {
  var store = router.get('store'),
      boardName = event.context; // you pass the (data|data container) here. In the view: {{action saveAndReturnSomewhere context="..."}}
  store.createRecord(App.Board, {
    title: boardName
  });
  store.commit();
  router.transitionTo('somewhere');
}

重构后的示例

我建议使用以下路由:

  • show: 显示已存在的项目,
  • edit: 提供输入项目字段的建议

在包含路由中添加以下事件处理程序:

  • createItem: 创建新记录并转到 edit 路由,例如
  • editItem: 转到 edit 路由

edit 路由中添加以下事件处理程序:

  • saveItem: 将提交存储并转到 show 路由,例如

5
这似乎不太对。你是从路由器提交到商店?这明显应该由控制器完成,路由器只负责处理路由和绑定数据给控制器。否则它很可能变成一个处理所有UI逻辑的大型开关/情况语句。 - Charlie
1
这几乎是正确的:路由器是UI管理和处理用户操作的核心。我只是试图与您分享我从Tom Dale那里获得的知识,所以路由器就是这样设计的... :-) 实际上,“控制器”这个名称不应与“传统”的MVC控制器混淆。实际上,在Ember语境中,它只是一个数据包装器,没有太多作用。 - Mike Aski
1
@MikeAski,你知道在1.0.0-pre4版本的路由器中,这种方法是否仍然有效吗? - Jan Dupal
这没有意义(在Ember方面)。如果不在控制器内,我们如何删除对象并重定向? - Edward
2
@JanDupal 实际上,正如您所看到的,这个问题被标记为 ember-old-router,不再适用于当前的路由器。 - Mike Aski
显示剩余5条评论

3

编辑:继续阅读,Mike的回答讨论了一些这种方法存在的问题。

您可以直接在路由器上调用transitionTo。如果您使用默认值,则应如下所示:App.router.transitionTo('route', context)


4
更好的实现方案应该使用 target 属性而不是使用 App.router 实例 _(特别是在测试时更好)_。 - Mike Aski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接