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:
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
transitionTonever updated the URL after a transition, and- 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.