Skip to content

Instantly share code, notes, and snippets.

@machty
Last active December 15, 2015 16:48
Show Gist options
  • Select an option

  • Save machty/5291307 to your computer and use it in GitHub Desktop.

Select an option

Save machty/5291307 to your computer and use it in GitHub Desktop.
old router and new router, sittin in a tree

Proposal: Generalize the Router DSL, Allow for Multiple "Routers"

Presently, you can't even use StateManager for managing the outlets of a modal view without hacking at the internals of Ember.Route, where all the rendering logic presently resides. There's a few ways we could go about exposing this, such as creating a RendererMixin, exposed to Ember.Route and Ember.State from ember-states, and some other folk are considering an Ember.Control to solve this problem.

But I'm of the mindset that Ember.Router and router.js provide all of the state manager functionality desired for solving the problems specific to both URL routing and state manager-based outlet rendering, not to mention state-based architecture, event bubbling, etc. I'd like to push StateManager off into the horizon and set it ablaze, and here's an idea of what could follow:

Make it possible to instantiate multiple "routers"/state managers managed by router.js.

A strictly state manager is just an Ember.Router where none of the states are accessible via URL. For instance, Ember.Router would just be a boring ol state manager if

  1. transitionTo never updated the URL after a transition, and
  2. URL changes never fired a router transition

So, why don't we make it possible/easy to define state managers for things like modals, leveraging the lovely new DSL, all under the assumption that the states are just routes inaccessible by URL.

Let's also throw a bone to the folk that still dig the classic StateManager api, before it was encumbered by logic pertaining only to states. Here's an idea:

# Ember.Router.define uses the same DSL as `map`, though the 
# plan is to enhance the DSL for both, and `define` returns a 
# subclass of `Ember.Router` that's tied to the state chart 
# drawn out by the DSL.
ModalStateMachine = Ember.Router.define ->

  # a `state` is a `route` inaccessibly by URL
  @state 'hidden'

  # We'd like this state to be instantiated with a specific class
  @state 'fadingIn', App.AnimatingState
  @state 'fadingOut', App.AnimatingState

  # Define a parent state, provide the class to use (optional of
  # course), and begin defining its substates. Maybe I'm wrong, but I
  # don't think we should split this into a separate method like
  # `route` vs. `resource`.
  @state 'visible', App.VisibleState, ->
    # Possible idea for devotees of old router / present StateManager
    # API: provide a `properties` method for defining the props 
    # passed to the `.create` of the route/state used for this state.
    # Note: we could also make it `@properties = {}`
    @properties
      activate: ->
        alert 'welcome to the visible state'

    @state 'start'
    @state 'form', ->
      @state 'basic_info'
      @state 'billing_info'

    @state 'confirm'
    @state 'success'

App.MyModalController = Ember.ObjectController.extend
  # This approach is not presently supported; router.js
  # terminates an event when no one responds to it, but if 
  # there are multiple "routers", I'd like for, say, modal
  # state machines to bubble their `send`s to the 
  # application router.
  target: ModalRouterClass.create
    

# TBD: How to use {{render}} logic from outside of templates?

It's important to note that this.state would also be valid DSL for the Application Router, since we need a way to define URL-less states even in the main router.

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