-
Notifications
You must be signed in to change notification settings - Fork 25k
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
feat(router): Allow for custom router outlet implementations #40827
Conversation
98d6293
to
ff4eedf
Compare
ff4eedf
to
bd118ed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks @atscott 👍
Reviewed-for: public-api
You can preview 98d6293 at https://pr40827-98d6293.ngbuilds.io/. |
bd118ed
to
aeaae1e
Compare
You can preview aeaae1e at https://pr40827-aeaae1e.ngbuilds.io/. |
This PR formalizes, documents, and makes public the router outlet contract. The set of `RouterOutlet` methods used by the `Router` has not changed in over 4 years, since the introduction of route reuse strategies. Creation of custom router outlets is already possible and is used by the Ionic framework (https://github.com/ionic-team/ionic-framework/blob/master/angular/src/directives/navigation/ion-router-outlet.ts). There is a small "hack" that is needed to make this work, which is that outlets must register with `ChildrenOutletContexts`, but it currently only accepts our `RouterOutlet`. By exposing the interface the `Router` uses to activate and deactivate routes through outlets, we allow for developers to more easily and safely extend the `Router` and have fine-tuned control over navigation and component activation that fits project requirements.
aeaae1e
to
6d2d33c
Compare
You can preview 6d2d33c at https://pr40827-6d2d33c.ngbuilds.io/. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should creating a custom router-outlet also be documented in the router guide?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🍪
reviewed-for: public-api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally I would have expected the interface to be RouterOutlet
and then our implementation to be something like DefaultRouterOutlet
. I assume that changing the name of this class would be a breaking change?
Adding Contract
to the end appears to be a workaround to avoid such a breaking change, but it feels like a new naming convention that we have not used in any of the rest of the framework, and so a bit out of place or awkward.
Could we consider how bad the breaking change would be to change the class name?
@petebacondarwin Yea, this was done to avoid the breaking change. I am open to bikeshedding the name of the interface but strongly feel that changing the class name would be a mistake even though the migration wouldn't necessarily be difficult. My two bullet points on this are:
If we decide that there's no good interface name, I'd be more inclined to scrap this PR entirely. What about
@jelbourn I don't feel that this is necessary at the moment. If it seems like something more devs are beginning to use, we could add something. For now, I think it's more of something that would be discovered organically from absolute necessity of needing to modify the built-in outlet behavior. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh if only we could have called it RouterOutletDirective
🥰
I wonder how many applications actually refer to the class itself? I guess it could be injected into child components/directices?
If we can't change the name of the class then I'm happy to go with ...Contract
as the interface. We could bikeshed it but I don't think there is likely to be a better name.
Reviewed-for: public-api
That's a great question. I believe we could use this PR as an example and try to come up with (and document?) the naming convention/recommendation for the interfaces/abstract classes/regular classes that we use in public API (so that we are consistent). As a part of this discussion we can look at existing patterns in the framework as well (to see if there are some similar cases). Since this PR doesn't target "patch" (so it'd be a part of v12), this should not delay the changes. @petebacondarwin @atscott what do you think? |
@AndrewKushnir - I feel that the boat has sailed for this case, but it would be good to discuss naming conventions going forward. Or at least discuss the potential difficulties that could come up when trying to future proof choices of names. |
Not many: only about 60 in all of g3. Of these, I think the most common use-case is |
You can preview 03c7c23 at https://pr40827-03c7c23.ngbuilds.io/. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM; I agree that the Contract
part of the name is a bit unfortunate for its inconsistency, but this is a niche enough API that I don't think it's a huge deal
Reviewed-for: public-api
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This PR formalizes, documents, and makes public the router outlet contract.
The set of
RouterOutlet
methods used by theRouter
has not changedin over 4 years, since the introduction of route reuse strategies.
Creation of custom router outlets is already possible and is used by the
Ionic framework (https://github.com/ionic-team/ionic-framework/blob/master/angular/src/directives/navigation/ion-router-outlet.ts).
There is a small "hack" that is needed to make this work, which is that
outlets must register with
ChildrenOutletContexts
, but it currentlyonly accepts our
RouterOutlet
.By exposing the interface the
Router
uses to activate and deactivateroutes through outlets, we allow for developers to more easily and safely
extend the
Router
and have fine-tuned control over navigation and componentactivation that fits project requirements.
// cc @liamdebeasi @mhartington