What’s the best way to capture the current state of an Ember app, that is represented by the URL, and is compatible with transitionTo?
My first thought was to store currentRouteName along with the model using modelFor(currentRouteName). e.g.
// in some-route.js
var currentRouteName = this.controllerFor('application').get('currentRouteName')
var model = this.modelFor(currentRouteName)
…
// somewhere else
this.transitionTo(currentRouteName, model)
The downsides of this approach are that it will not work with nested resources (modelFor(routeName) only returns a single model), and it will require some additional work for use with query params.
Another approach might be to simply grab the path from window.location:
var currentPath = location.href.slice(location.href.indexOf(location.pathname))
…
// somewhere else
this.transitionTo(currentPath)
The downsides are that it may not work if the Ember app does not reside at the root url, and that it may run model hooks unnecessarily.
It feels like there should be a better way to do this. Am I missing something?
Just discovered that routes have access to the router, so my current thinking is to go with a initializer which makes each route store its path on its controller on willTransition. On subsequent transitions, the route can then decide whether to transition to its previous path:
// app/initializers/route.js
import Ember from 'ember';
var hasRun = false;
export default {
name: 'route',
initialize: function () {
// Prevents needless re-initialization
if (hasRun) { return; }
Ember.Route.reopen({
// Prefix with underscore. I'm not entirely sure why!
// see: https://github.com/emberjs/ember.js/issues/5394#issuecomment-52383989
_actions: {
// Stores the current path
didTransition: function () {
Ember.run.next(this, function () {
this.set('path', this.get('router.url'));
});
return true;
},
// Sets the previous path on the controller.
// Allows routes to return to a previous state.
willTransition: function () {
this.get('controller').set('previousPath', this.get('path'));
return true;
}
}
});
}
};
It’s not a case of going back to the previous state, but storing the the current state and being able to return to it at any point in the apps lifecycle.
I found that setting the previousPath in the application controller rather than the current controller made easier accessible to the post-transition controller. Great solution!