Implement the Route Manager API (RFC #1169) - #21460
Conversation
Introduce a Route Manager layer between the router and route base classes so the router drives routes through a well-defined manager interface instead of calling classic Route methods directly. This decouples the router from the classic Route and is the stepping stone toward alternative route base classes and a future router. Add the manager interface, capabilities, and registration, implement a ClassicRouteManager that encapsulates today's classic Route behaviour behind it, and make router_js dispatch lifecycle, rendering, model resolution, and the classic-interop surface through the manager.
37bd3e6 to
7582a9f
Compare
…s on emberjs#21460 Reverts the outlet.ts compute-ref guard to the current ember-7.0.0 behavior, demonstrating that the @model-during-willDestroy instability (emberjs#18987) still reproduces on top of the Route Manager RFC implementation (emberjs#21460). The smoke-test job's '@model stability during route transitions' tests are expected to fail here. Not for merge.
refactor: add manager.getRoute(bucket)
…d through `setOutletState`
| /** | ||
| * Appends `into` without clearing the target first. Mimics the `appendTo` behavior for classic components. | ||
| */ | ||
| appendIntoTarget?: boolean; |
There was a problem hiding this comment.
Porting over a comment from @NullVoxPopuli
this will need a bunch more tests <3
in particular:
renderCompnoent(A, { appendTo: IntoTarget })
renderComponent(B, { appendTo: IntoTarget })
and do the reactivity of A and B stay in the same location and not re-order themselves?
(This was the issue I ran in to during implementation, in that whatever was updated last would become last in DOM-order)
(also, I think this behavior will need its own RFC, describing the stability of render-order (and update-order), and probably appendTo rather than a booling, imo -- boolean configurable options are a bit of an ick for me)
There was a problem hiding this comment.
we should pull this out in to a separate PR and discuss test cases here -- I tried to implement this in an earlier iteration of renderComponent, and backed it out due to ordering-inconsistencies upon update of tracked state within the root region of the rendered area
There was a problem hiding this comment.
potentially related: #21551
(rendering in to "Node"s rather than elements)
…anager test: scenario funky route manager
Experiment/classic outlet probes
# Conflicts: # packages/@ember/-internals/glimmer/index.ts # packages/@ember/-internals/glimmer/lib/syntax/outlet.ts
| view.appendTo(this.rootElement!); | ||
| renderRootComponent(component: object) { | ||
| setRenderer(this, this.lookup('renderer:-dom') as BaseRenderer); | ||
| renderComponent(component, { into: this.rootElement!, owner: this, appendIntoTarget: true }); |
There was a problem hiding this comment.
destruction handling?
let { destroy } = renderComponent(...);
registerDestructor(this, destroy);
This is a big PR for a big feature.
Introduces a Route Manager layer between the router and route base classes so the router drives routes through a well-defined manager interface instead of calling classic Route methods directly. This decouples the router from the classic Route and is the stepping stone toward alternative route base classes and a future router. The classic Route behaves exactly as before, there are no changes to app authoring.
Three layers, top to bottom:
@ember/routingpublic re-exports of the authoring API@ember/-internals/routing/route-managersThe classic route manager and route manager infrastructurerouter_jsDrives the routes lifecycle through the manager, and owns the route manager contractWhy does the outlet have a legacy path?
A handful of tests directly set the outlet state, one in particular is testing something for liquid-fire. If there are addons or user code that expects to be able to create their own render state, they will not include the route wrapper and invokable we expect from the route manager, the legacy path path lets them continue working.
Query Params
The current implementation of query params is driven by the router, I have gated the parts that directly reach into routes behind the classic interop capability of route managers. I have left the "machinery" in place in the router. When we come to replace the router, a decision will need to be made if we bridge the classic router manager to use whatever new QP implementation we come up with, or if we fully migrate the router.js QP implementation to be fully encapsulated by the classic route manager.
RFC #1169