EmberJS: How to transition to a router from a cont

2019-03-09 23:40发布

问题:

I have an action:

{{action create target="controller"}}

which I have targeted to the bound controller (rather than the router) like this:

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

How do I redirect back to a route from the controller action?

回答1:

In fact, this is not Ember idiomatic. From what I know, and what I have learnt from Tom Dale himself, here are some remarks about that code:

  • First, you should not transitionTo from elsewhere than inside the router: by doing so, you are exposing yourself to serious issues as you don't know in which state is the router, so to keep stuff running, you will quickly have to degrade your design, and by the way the overall quality of you code, and finally the stability of your app,
  • Second, the action content you are showing should be located inside the router to avoid undesired context execution. The router is indeed a way to enforce a coherent behavior for the whole app, with actions being processed only in certain states. While you are putting the actions implementation into Controllers, those actions can be called at anytime, any including wrong...
  • Finally, Ember's controllers are not aimed to contain behavior as they rather are value-added wrappers, holding mainly computed properties. If you nevertheless want to factorize primitives, maybe the model can be a good place, or a third party context, but certainly not the Controller.

You should definitely put the action inside the router, and transitionTo accordingly.

Hope this will help.

UPDATE

First example (close to your sample)

In the appropriated route:

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');
}

Refactored example

I would recommend having the following routes:

  • show: displays an existing item,
  • edit: proposes to input item's fields

Into the enclosing route, following event handlers:

  • createItem: create a new record and transitionTo edit route, e.g
  • editItem: transitionTo edit route

Into the edit route, following event handlers:

  • saveItem: which will commit store and transitionTo show route, e.g


回答2:

Use transitionToRoute('route') to redirect inside an Ember controller action:

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


回答3:

EDIT: Keep reading, Mike's answer discusses some of the problems with this approach.

You can just call transitionTo directly on the router. If you are using defaults this looks like App.router.transitionTo('route', context).