If you've filled out some fields in a navigate elsewhere, either via a back button, URL change, or linkTo
transition, there should be a way to intercept that transition and make the user confirm they want to perform the transition.
Use routeTo
handler on form route. Bubble the event if user confirms
navigation.
When you click "Connect" or "Discover" on Twitter, and their data hasn't been loaded yet, a spinner is presented at the top until the data comes back in, and then the template teardown/rendering happens.
Presently, this behavior can be somewhat approximated using LoadingRoute
,
but that's only for handleURL
URL transitions, and not transitionTo
,
which doesn't pause even if it's provided unresolved promise contexts.
This is now the default for handleURL
or transitionTo
with promises.
Can also use beforeModel
and afterModel
to return a delayed promise.
But if you wanted to put up a spinner and remove it once the route
loaded, you could (among a lot of other things), have the following:
routeTo: function(transitionEvent) {
var controller = this.controller;
controller.toggleLoadingSpinner(true);
function removeSpinner() { vontroller.toggleLoadingSpinner(false); }
transitionEvent.perform().then(removeSpinner, removeSpinner);
return true;
}
While the above-described transition is taking place, what should happen when you click another link, or navigate back, or some event/timer fires? How should that be handled, keeping in mind that one app might want to enqueue transitions, another might want to cancel the current one and start in on the second, etc.
Ideas(s):
- The proposed
routeTo
event takes aTransitionEvent
object. We could make this event a promise that resolves when a transition completes, which could be used for enqueuing.
No full answer yet that doesn't change UI, but you could do something like this on a pivot point.
// transition from foo.bar to foo.bar
// define the following on FooRoute (the shared parent pivot route).
routeTo: function() {
// Perform immediate transition. This will perform any template
// teardown on `bar`, even if its outlets don't get replaced
// by whatever's in `foo.loading`
this.transitionTo('foo.loading');
return true;
}
Whether handleURL
or transitionTo
, an AdminRoute
ought to be able to halt/redirect a transition to a subroute if the user isn't authenticated. The more generalized case is whenever a destination route's knowledge/responsibility determines whether a transition to it should occur. This is presently somewhat handleable, but I believe deserialization is still attempted on leaf routes even if a parent route redirects.
Unified behavior between transitionTo/handleURL, and extra hooks on Ember.Route.
You could do the follow either via shared mixin or a shared parent route:
App.AdminRoute = Ember.Route.extend({
beforeModel: function() {
return checkUserLoginStatus();
}
});
Try a link, get redirect to login, login, then resume.
Save the TransitionEvent somewhere, call perform on it later.
Luke Melia: A good use case for a non-routeable substate is saving. When we save a page's data in Yapp, we show a spinner and capture navigation events as a "nextAction". We refire that action once (and if) the save completes successfully. Last click wins. This is more intuitive than blackholing everything or queuing up multiple actions.
Override routeTo
on leaf route. Save TransitionEvent, refire the most
recent one once saving is done.
This is straight from the Embercasts site (which makes us of routeTo
to accomplish this): we have sidebar links to Embercasts that'll take you directly to a page with a video to watch that embercast, but we also have an index page where you can scroll through multiple watchable embercasts on the same page. If you click a sidebar link and an Embercast is already on that page, just scroll down to it and update the URL. This should also work with clicking Back and Forwards.
First off, you should use actions for this if possible. Catch an
occasion called goToThing
and then this route will know how to
specifically handle it. But if you want to catch URL transitions as
well, then you probably have to look at the destination URL of the
URL and perform a regex, maybe use some router.js function to get the
params, etc etc etc... This is tricky and highly depends on the app work
flow, but this is doable.
Ok!!!
A good use case for a non-routeable substate is saving. When we save a page's data in Yapp, we show a spinner and capture navigation events as a "nextAction". We refire that action once (and if) the save completes successfully. Last click wins. This is more intuitive than blackholing everything or queuing up multiple actions.