Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX canary] Decouple route transition from view creation #10372

Merged
merged 1 commit into from
Feb 8, 2015

Commits on Feb 8, 2015

  1. [BUGFIX canary] Decouple route transition from view creation

    This closes emberjs#9814 and closes emberjs#10304, which are examples of a class of
    problems caused by the way the router synchronously reaches into the
    view hierarchy to set outlet state. It is a significant refactor of the
    way the router communicates state to outlets.
    
    What motivates this change?
    
     - Simple examples like `{{#if something}}{{outlet}}{{/if}}` are
       incorrect under the current model.
    
     - Richer examples like block-helpers to enable animation also
       suffer. In general, the router cannot know when and whether a
       particular outlet is going to exist, and it shouldn't need to know.
    
     - The router maintains a bunch of view-related state that is actually
       redundant with the view hierarchy itself, leading to unnecessary
       complexity.
    
     - This eliminates the longstanding weirdness & confusion caused by the
       fact that we used to create new `View` instances and then throw them
       away if they looked similar enough to ones that were already
       rendered. That functionality is now covered by state diffing in the
       `OutletView`.
    
     - We reduce the API surface area between router and view layer in a way
       that should make it easier to experiment with swapping in compatible
       implementations of either.
    
     - As a bonus, this changes makes outlets work in an observer-free way
       that will make them easy to integrate with upcoming planned view
       layer optimizations.
    
    How does this work?
    
     - Rather than directly building and linking views, the router builds up
       an abstract summary of the render decisions that have been made by
       the current routes.
    
     - This state is cheap to recalculate as needed. It doesn't do any view
       creation. To avoid expensive observer creation & teardown, we just
       recreate the whole thing and use a `setState`-like mechanism to
       propagate the changes through the outlet hierarchy. This gives us
       optimal granularity of updates.
    
     - Actual view instantiation moves into the OutletView -- within the
       view layer where it belongs. Each outlet does a diff to see whether
       it should rerender itself or propagate inner changes down to its
       child outlets.
    
     - To bootstrap rendering, the router creates a single top-level outlet,
       after which all view creation is internal to the view layer.
    
    Does this break any existing semantics?
    
     - No, as far as I can tell.
    
    Could this get even better if we decided to deprecate some old
    semantics?
    
     - Yes. It would be better if users` `renderTemplate` implementations on
       `Route`s were required to be idempotent. Then we could eliminate a
       bunch of the remaining state from them.
    
     - Also, when we deprecate the `render` helper we can eliminate the
       remaining use of `_activeViews` state tracking on the router. That is
       the only remaining use for it.
    ef4 committed Feb 8, 2015
    Configuration menu
    Copy the full SHA
    ba1d1a6 View commit details
    Browse the repository at this point in the history