-
-
Notifications
You must be signed in to change notification settings - Fork 407
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
Public router service #819
base: master
Are you sure you want to change the base?
Conversation
Thanks for writing this up! One question I have: is the idea that the router subclass could override all parent methods? Or should some of them be |
@chriskrycho as currently only methods listed as part of public API are actually implemented in |
Confirm what @SergeAstapov said, currently there is no private API in the router service, and Ideally it stays that way (basically as more of an interface). This has the practical effect that at least (for now) overridden methods should eventually call I considered whether we should call this out in the RFC and opted against, mostly because it seemed to fall under "public APIs are public" and telling someone they must call super and must extend the base-class would artificially (and only pedantically) limit experimentation in this layer that is desired. |
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.
I really loved this RFC, thanks for doing that @SergeAstapov, but I think we need to keep the readability and isolation principle on top of our head to keep moving on in a direction to provide compatibility without losing the ergonomy 😄
* links to external routes in templates within the engine rendered via `<LinkTo />` component: | ||
|
||
```hbs | ||
<LinkTo @route="external-route">Go Somewhere</LinkTo> |
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.
I'm still thinking that we should use <LinkTo @route="external.home">Go Somewhere</LinkTo>
where external
(hypothetical name) means a prefix that it's an external route. It's good for ergonomics because as a developer we don't want to go to externalRoutes definition and check if it's a internal or external route. I see the importance of deprecating <LinkToExternal/>
but I don't want to lose the readability that it means an external link without poking around the code.
Also it solve the drawback on this RFC 😄
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.
@villander this would prevent addons from utilizing LinkTo, which I think makes it a non-starter. It might be interesting to bring the external-routes map into routes.js
at some point to address this though so that there's only one location where valid routes may be defined. This would be outside the scope of this RFC.
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.
Looking for this perspective I agree with you @runspired I think we just need to find some way to don't make engines more confusing and harder to teach than it already is.
This is not viable long term solution as any changes made to `<LinkTo />` component in the Ember.js codebase | ||
would need to be backported to `ember-engines`. | ||
|
||
* Deprecate and remove `externalRoutes` mapping. |
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.
🚨 It breaks the isolation principle around ember-engines, where every engine could access any outside contexts without asking for it, going in the opposite direction of code isolation proposed by Engines.
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.
right, that's why though this is an alternative it's not the suggested path of the RFC
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.
Surely, just wanted to highlight and provide a reminder/support to the next reviews 😃
|
||
1. Replace use of `<LinkToExternal @route="external-route" />` component | ||
with `<LinkTo @route="external-route" />` in every engine codebase. | ||
2. Users using `ember-engines-router-service` would need to replace any of its usage with |
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.
2. Users using `ember-engines-router-service` would need to replace any of its usage with | |
2. Users using [ember-engines-router-service](https://github.com/villander/ember-engines-router-service) would need to replace any of its usage with |
export default class extends Component { | ||
@service router; | ||
@action clickLink () { | ||
this.router.transitionTo('external-route'); |
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.
Also, I'd like to have something like that to don't lose the explicit outside context on engines. @rwjblue @dgeb and I made huge progress on that in the past - ember-engines/ember-engines#779
import { external } from 'ember-engines/helper'
...
@action
clickLink () {
this.router.transitionTo(external('external-route'));
}
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.
It feels unnecessary to impose an extra function call on users to mark something as external when it has already been defined as external in their router configuration (see also comments above on external.
). Similarly, this would prevent addons from making use of the router service cleanly.
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.
It depends, I kinda agree with you that mapping those things on the router configuration clarifies things on a certain level, but I love readable and explicit code. How would you realize just looking for a ton of transitionTo
in your code that those routes are from the host app? imagine you have at least 50 occurrences how many are linking outside context? Correct me if I'm wrong, IMO is necessary back in forth on the router configuration to realize those things.
Re: "no private API"—I want to be clear here about two things:
Net, I think that it's worth being very explicit and intentional about this question and I would actually like to see it addressed explicitly in the RFC. I'd also like to see some actual analysis of the existing public API: do we actually want to say that it's fine for subclasses to override the definition of Accordingly, I think it would be helpful to delineate, for each of these (perhaps at the category level if appropriate, but at a per-item level if that is more appropriate in other cases) whether it should be overridable by subclasses or not— Methods: Properties: Events: Bonus doh comment: it can’t actually use |
I don't have a ton of context on this, but maybe this comment from @ef4 will be important/useful to y'all since you have been thinking about it? |
This RFC seeks to provide a solution that also solves another DX issue faced by engines developers. | ||
|
||
Authors of large scale applications often create an addon(s) to contain reusable components that can | ||
be rendered either in the context of the host App or Engine. In such scenarios an extra guard needs |
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.
this is also solved by using hrefs instead of route/model/query args of the default link-to.
with an a
tag with preventDefault
d click handler, we can use the router service to detect when an href is in the route, or in an external app, and appropriately "do the right thing.
I like this approach because it means we:
- don't need extra components for each type of usage
- uses the existing href knowledge that everyone already understands with
<a>
- aligns with: (the spirit of): Implement in-app transitions for native anchor elements so that LinkTo isn't needed ember.js#19271 and Router Helpers #391
here is a demo: https://codesandbox.io/s/custom-link-component-dgbxl?file=/app/components/link.hbs
(this demo is incomplete, but gives the gist).
(except codesandbox doesn't work so... 🤷 (this sandbox has been untouched since 3.21, and the dependency checker is preventing start up... idk what's going on. ))
where improvements could be made here where <LinkTo>
is a bit better at:
- query-param only transitions
- sticky query params
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.
though, unifying on LinkTo is still a good improvement!
(over multiple components)
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.
This RFC is what would make those router helpers and the href approach work correctly for engines as well.
It looks like this has some interest so we should work to keep it moving. |
Can we move this forward? |
Can we move this to Exploring? |
We had some back and forth in the Review meeting today around whether this should move to Exploring or not. There's definitely agreement that this is a problem we need to resolve, but that it's probably not going to be something that we can resolve until the new router design is more finalized. |
Rendered