33
votes

I have a multi-step flow that the user can go through sequentially or jump straight to a section (if the sections in between are completed). I think this logic should be in the Route object. However, from within the controller, how do I access the route instance. For example, it would be ideal to be able to do something like this in the controller:

App.Flow = Em.ObjectController.extend({
  submit: function(){
    // Validation and XHR requests
    // ...

    // Go to the next step
    route.goToNextStep();
  }
}
4

4 Answers

41
votes

From within a controller, you can access the router via this.get('target'). So this.get('target').send('goToNextStep') should work.

Like so:

App.Flow = Em.ObjectController.extend({
  submit: function(){
    // ...
    this.get('target').send('gotoNextStep');
  }
}

App.FlowRoute = Ember.Route.extend({
  events: {
    gotoNextStep: function(){
      // ...
      this.transitionTo(routeName);
    }
  }
}
2
votes

You need to get the route for such conditions, so from the controller just say,

App.Flow = Em.ObjectController.extend({
  submit: function(){
    var self =this;
    // Validation and XHR requests
    // ...

    // Go to the next step
    self.send('goToNextStep');
  }
}

and define your goToNextStep event in your route's event hash

0
votes

'this' is what points to the router, but you shouldn't add any methods to that prototype. Instead, make some sort of event that triggers the transition to the next step.

0
votes

In addition to target, another way to do this in Ember now is with getOwner.

For example, to send an action to your application route:

import Component from '@ember/component';
import { action } from '@ember/object'; // https://github.com/pzuraq/ember-decorators-polyfill
import { getOwner } from '@ember/application';

export default class MyTopLevelComponent extends Component {
    @action
    closeModal() {
      getOwner(this).lookup('route:application').send('closeModal');
    }
});