-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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 MVP #14805
Public Router service MVP #14805
Conversation
urlFor() { | ||
let router = get(this, 'router'); | ||
|
||
return router.generate(...arguments); |
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.
Doesn't this still take the slow path with the QPs?
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.
Good question. Will verify.
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.
Removing until we verify the implementation details.
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.
Any API that doesn't meet the RFC here https://github.com/emberjs/rfcs/blob/master/text/0095-router-service.md#query-parameter-semantics shouldn't be included until it does.
☔ The latest upstream changes (presumably #14806) made this pull request unmergeable. Please resolve the merge conflicts. |
Added tests for |
@krisselden I've stripped the |
d88ba0f
to
eb763a9
Compare
@@ -34,6 +34,8 @@ import ApplicationInstance from './application-instance'; | |||
import { privatize as P } from 'container'; | |||
import Engine from './engine'; | |||
import { setupApplicationRegistry } from 'ember-glimmer'; | |||
import RouterService from 'ember-routing/services/router'; | |||
import isEnabled from 'ember-metal/features'; |
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.
import { isFeatureEnabled } from 'ember-metal';
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.
Done
@@ -34,6 +34,8 @@ import ApplicationInstance from './application-instance'; | |||
import { privatize as P } from 'container'; | |||
import Engine from './engine'; | |||
import { setupApplicationRegistry } from 'ember-glimmer'; | |||
import RouterService from 'ember-routing/services/router'; |
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.
import { RouterService } from 'ember-routing';
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.
Done
@submodule ember-routing | ||
*/ | ||
|
||
import Service from 'ember-runtime/system/service'; |
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.
Imports should be from the entry points (e.g. from 'ember-runtime';
instead of from 'ember-runtime/somethign';
)
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.
Done
containing a mapping of query parameters | ||
@return {Transition} the transition object associated with this | ||
attempted transition | ||
@public |
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.
We should add @category ember-routing-router-service
so that the YUIDoc will be able to remove these until the feature is enabled
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.
Done
@public | ||
*/ | ||
transitionTo() { | ||
let router = get(this, 'router'); |
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.
Since this is injected we should be able to swap this to just this.router
here.
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.
Done
get | ||
} from 'ember-metal'; | ||
import { jQuery } from 'ember-views'; | ||
import { inject } from 'ember-runtime'; |
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.
Group with the ember-runtime
import above...
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.
Done.
import { inject } from 'ember-runtime'; | ||
import { ApplicationTestCase, moduleFor } from 'internal-test-helpers'; | ||
|
||
import isEnabled from 'ember-metal/features'; |
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.
import { isFeatureEnabled } from 'ember-metal';
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.
Done
this.registerRoute('parent', Route.extend({ | ||
router: inject.service(), | ||
init() { | ||
routerService = get(this, 'router'); |
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.
we should call _super
before this
here
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.
Done for all inits.
return this.visit('/child').then(() => { | ||
assert.equal(routerService.get('currentRouteName'), 'parent.child'); | ||
|
||
return this.visit('/sister').then(() => { |
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.
return this.visit('/child').then(() => {
return this.visit('/sister');
}).then(() => {
assert.equal(routerService.get('currentRouteName'), 'parent.sister');
return this.visit('/brother');
}).then(() => {
assert.equal(routerService.get('currentRouteName'), 'parent.brother');
});
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.
Done
currentRouteName: readOnly('router.currentRouteName'), | ||
currentURL: readOnly('router.location.path'), | ||
location: readOnly('router.location'), | ||
rootUrL: readOnly('router.rootURL'), |
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.
Correct the casing here (I think it should be rootURL
)
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.
Done
import { get } from 'ember-metal'; | ||
import RouterDSL from '../system/dsl'; | ||
|
||
/* |
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.
The docstrings don't seem to match out usual style, see Router for example.
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'll update.
I'd love @ef4 review to see if there is any concern about the timing of when these properties update as compared to the RFC, I know that the RFC was a chance to improve the router not just give it a prettier 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.
This is looking really good! I'm glad you got to the bottom of that currentURL
async issue we chatted about. 👏
I think the only real thing missing here at this point are some tests for .transitionTo
, .rootURL
, and .location
properties.
Service, | ||
readOnly | ||
} from 'ember-runtime'; | ||
import { get, descriptor } from 'ember-metal'; |
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.
Descriptor seems unused
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'll remove it. Thanks!
@@ -629,6 +633,7 @@ const EmberRouter = EmberObject.extend(Evented, { | |||
|
|||
let doUpdateURL = function() { | |||
location.setURL(lastURL); | |||
set(emberRouter, 'currentURL', lastURL); |
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 think we should actually do this in the router.updateURL
and router.replaceURL
methods directly above the run.once(doUpdateURL)
bit...
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 can do that. My thought was I wanted to keep both set calls in the same place, but these methods are so closely related that it's find either way.
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.
Ah, so it turns out that setting this after a scheduled call is what's fixing this issue. So, it looks like I have to leave it where it is.
|
||
set(router, 'currentPath', path); | ||
set(router, 'currentRouteName', currentRouteName); | ||
set(router, 'currentURL', currentURL); |
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 would think this change is not needed since we are setting router.currentURL
above in the changes to _setupRouter
.
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 thought this too, initially. It turns out that there's a different codepath whether you're visiting vs. transitioning, and we need this update to occur in both places. I think this surfaces part of @krisselden's concerns, where we want to take advantage, while we have the engine out on the floor, to refactor this to make it cleaner and more consistent.
access to the router. | ||
|
||
@public | ||
@class RouterService |
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 add the @category ember-routing-router-service
flag here too (so that while the feature is pending it isn't listed in emberjs.com/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.
Done!
@rwjblue thanks for the additional comments. I'm adding tests for the outstanding properties/method now - mainly taking it slow so I make sure I cover high value test cases. |
@krisselden I appreciate you wanting to make sure we're focussing on the right things with this PR, in terms of the opportunity to improve the router in general. This intent of this particular PR is to get a useful public API for the router in the hands of devs sooner rather than later. This will help provide immediate value, but does not preclude us circling back and refactoring parts of the internals later. In fact, that's our direct intention. We wanted to try to restrict these changes to simple, surface level changes before we get into the more meaty implementation, specifically the refactoring to use I'll update the PR's description above to indicate the 4 phases, as discussed by @rwjblue and I. |
This is super exciting. Thank you for taking this on and helping driving it home. One additional thing I'd really like to see fall into one of the later phases is some mechanism for components to subscribe to |
return this.visit('/').then(() => { | ||
let location = routerService.get('location'); | ||
assert.ok(location); | ||
assert.ok(location instanceof Ember.NoneLocation); |
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 should be imported from ember-routing/locations/none
(using global Ember
within Ember or the test suite isn't allowed). This is currently causing the linting tests to fail...
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 weird. I didn't see that failure. Will fix right now!
routerService: inject.service('router'), | ||
init() { | ||
this._super(); | ||
set(this.router, 'rootURL', '/test'); |
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 have a slight preference to use something other than /test
here (since when tests are running we are already in /tests
path). It definitely doesn't matter for this test as written, but it would just make this a tad bit easier for my brain to parse 😝
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.
Will change to /brainparse
immediately! :)
|
||
return this.visit('/').then(() => { | ||
this.assertText('/'); | ||
}); |
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.
Can you add an update and reset phase to this (kinda like the INUR stuff for the glimmer tests)?
I'm thinking something like:
.then(() => routerService.transitionTo('child'))
.then(() => this.assertText('/child'))
.then(() => routerService.transitionTo('/'))
.then(() => this.assertText('/'))
}) | ||
.then(() => { | ||
this.assertText('/child'); | ||
}); |
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.
Can you add the update and reset steps (similar to comment for test above)?
Router Service RFC
b38c1d5
to
7daa911
Compare
@workmanw The RFC introduces the |
What about rest of features covered by RFC (RouteInfo, transition events ...) ? is there any subsequent issue to track it ? |
@janmisek There is not. |
And are these features still planned for implementation ? |
Yes, the RFC is merged which means anyone can PR the features. I started on several of them but had to back off to clear some other blockers first. |
This PR represents the MVP of the public router service described in this RFC. It incorporates work done by @locks in this PR.
It includes a minimal API:
currentRouteName
currentURL
location
rootURL
transitionTo
Status: Work in progress
Reviewers: @locks @rwjblue @ef4
Changes:
ember-routing-router-service
feature flagHow to test drive this PR:
yarn start
http://localhost:4200/tests/index.html
, one withEnable Opt Features
checked, ensure tests passTODO:
Write tests for
currentRouteName
currentURL
location
rootURL
transitionTo
RFC Implementation Phases
urlFor
, ensuring correct performance profileRouteInfo
and associated API