I'm migrating an existing Polymer-based application to Polymer 2, and one thing the Polymer 2 upgrade guide is annoyingly silent about is how to update the routing code to work with the updated app-route
and all its "routing encapsulation" system.
With Starter Kit 1, we had the page()
function, so an event handler that wanted to change the current route simply ran page("/new_page")
.
With Polymer 2, I've discovered several different approaches to affect route changes:
1. Create a custom event handling setup for your application:
Main
<app-location route="{{route}}"></app-location>
<app-route route="{{route}}" pattern="/:page" ...></app-route>
...
ready() {
super.ready();
window.addEventListener('change-route', e => this.set('route.path', e.detail));
}
...
View
...
handleGoToOtherPage() {
window.dispatchEvent(new CustomEvent('change-route', { detail: '/new_page' }));
}
...
Cons: this is really cumbersome, especially the event dispatching.
2. Use Javascript History API
View
...
handleGoToOtherPage() {
window.history.pushState({}, null, '/new_page');
window.dispatchEvent(new CustomEvent('location-changed'));
}
...
Cons: I don't mind using just pushState()
, but pushing a new state is not enough as app-location
doesn't actually monitor the window location, so you need to "let it know" that it should re-read it. the result is code which is even more cumbersome than option 1, though thankfully I don't need to setup custom event handlers in the main app.
3. Use <iron-location>
to push location changes
View
...
<iron-location id="location"></iron-location>
...
handleGoToOtherPage() {
this.$.location.path = '/new_page';
}
...
Cons: I can only update the path
, query
and hash
separately, and if I update only one, I may get into trouble. Also, look hacky...
Summary
Which method do you think is The Right Thing(tm)?
Do you have another method that is better?