These are the things that I don't believe is totally consistent and things I think might give problems in different situations. We don't have to solve them all, but make sure that we don't get ourselves into something that's going to be hard to solve.
.dispatch(or.perform,.resendor whatever we're gonna call it) needs to be supported in a consistent way.- Retrying with previously rejected promises.
- Should contain the full target route path. It doesn't matter where it came from.
- Does
TransitionEventreplicate itself, or does it have anEventDescriptorthat can be reused? Important thing is that we don't reuse the sameTransitionEventinstance, as this will mean trouble regardingisAbortedand resolved contexts. - How do you put extra state on a
TransitionEventthat must survive after calling.dispatch? Do you just add properties to it, or should it have adataproperty that you need to add properties about the transition to (e.g.transitionEvent.data.startTime = new Date().
- There should only be one
activeTransitionEventon the router.TransitionEventshould have anisAbortedboolean property that hooks with multiple async steps can use to check if they should continue or not. When a new transition is started (.transitionTo,{{linkTo}}or.dispatch), the previous one is aborted and the new one becomes theactiveTransitionEvent. - Consistent return values from
router.modelFor. We talked about deprecatingrouter.modelFor, and create a new method onTransitionEventalso calledmodelFor, that returns the model for a given route name as it would be if/when the transition is finished. If you want the current model you're probably either in a controller, and should useneeds, or you can usethis.controllerFor('user').get('model'). A model is not active until it's on the controller. - What's the point of
routeTo? Why don't we just havetransitionTo, and it always bubbles anwillExitevent on all current routes? Then a.dispatchis always simply a newtransitionTocalled on the current route, no matter where we are at that point. - Should calling
.performonTransitionEventfrom within arouteToreally stop the bubbling? Why would a child route want to prevent its parent from doing its work?
I can't think of a good way to support retrying transitions with supplied contexts that are promises. There isn't a generic way to reload the data. Unless...
Let the transitionTo method accept "functions that returns promises" as context. Then every time a TransitionEvent is fired, that function is fired and returns a fresh promise that hasn't been resolved yet. It works kinda like Alex' Lazy Perserverant Promises, but doesn't set any demands for the promises themselves (they can be jqXHR, RSVP.Promise etc.). So, if a developer needs to be able to retry TransitionEvents with promises that can be rejected, he needs to do like this:
App.SomeController = Ember.Controller.extend({
username: '', //Bound to a textfield in the template
didClickButton: function() {
var username = this.get('username');
this.transitionTo('user', function() {
return $.get('/users/'+username);
});
}
});Let's say that the AJAX call returns with a 401 Unauthorized status code since the user's session has timed out. Then the jqXHR will be rejected. This will trigger an error (WHERE?). The error handler can then store the TransitionEvent in a transitionToPerformOnceLoggedIn property. Once the user has logged in, we call .perform() on the transitionToPerformOnceLoggedIn, which will once again send the GET request to /users/:username.
In cases where you know that the value has already been resolved, you don't need to incapsulate it in a function. This will work fine in all cases:
App.RepoController = Ember.Controller.extend({
needs: ['user'],
goToRepoOwner: function() {
this.transitionTo('user', this.get('controllers.user.model'));
}
});So this is not changing any old functionality. It's just a new option to use, which is necessary for repeated async lookups.
The only unknown I have here is: Who handles the error event? Is it an event that bubbles up from the current route. This probably makes the most sense, since you would probably have an error event handler in your App.ApplicationRoute that checks for 401 requests. Or is it called on the target route? How does it work in the code you've made so far?