Skip to content

Instantly share code, notes, and snippets.

@machty
Last active December 16, 2015 15:29
Show Gist options
  • Save machty/5455875 to your computer and use it in GitHub Desktop.
Save machty/5455875 to your computer and use it in GitHub Desktop.
A collection of use cases that Ember Router ought to support. Some of these may presently be implemented, but to varying degrees of quality/configurability/jankness; either way, the implementation may change so it's important that we preserve existing use cases. Also, not all of these needed to be specifically handled by Ember Core; rather, the …

Prevent transition when a form is half filled out

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.

Answer

Use routeTo handler on form route. Bubble the event if user confirms navigation.

Delayed "Twitter" transition, regardless of URL navigation / transitionTo

Twitter spinner

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.

Answer:

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

Twitter Continued: event handling during loading

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 a TransitionEvent object. We could make this event a promise that resolves when a transition completes, which could be used for enqueuing.

Answer

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

Redirect/halt links to Admin routes if user isn't authenticated

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.

Answer

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

Redirect/halt and remember/retry previous attempt

Try a link, get redirect to login, login, then resume.

Answer

Save the TransitionEvent somewhere, call perform on it later.

Disable Transitions while Saving

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.

Answer

Override routeTo on leaf route. Save TransitionEvent, refire the most recent one once saving is done.

Scroll to Content if Already Visible Rather than Transition

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.

Answer

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.

Explore States as a means for animation

Answer

Ok!!!

@lukemelia
Copy link

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.

@machty
Copy link
Author

machty commented Apr 25, 2013

Thanks @lukemelia, i'll update the list

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment