给定index.html
(my-app
(中包含iron-pages
的根组件,以及一个或多个页面中的iron-ajax
调用,子组件中的iron-ajax
on-response
函数告诉my-app
更改路由的最佳方法是什么?我正在使用聚合物 2。我看到示例依赖于不同组件中的链接,并调用同一组件,但没有从一个组件到其父组件的iron-ajax
。
在my-app.html
我有一个app-location
和app-route
,以及iron-pages
:
<app-location route="{{route}}"></app-location>
<app-route
route="{{route}}"
pattern="/:page"
data="{{routeData}}"
tail="{{subroute}}"></app-route>
<app-toolbar>...
<iron-pages role="main" selected="[[routeData.page]]"
attr-for-selected="name" selected-attribute="visible"
fallback-selection="404">
<my-login name="" route="[[subroute]]"></my-login>
<my-todos name="my-todos" route="[[subroute]]"></my-todos>
...
<my-404-warning name="404"></my-404-warning>
</iron-pages>
用户首先看到my-login
。当my-login
调用中的iron-ajax
完成时,我想用my-todos
替换my-login
。到目前为止,我已经提出了两种方法(见下文(。两者都有效 - 更改页面和更新URL - 但一个一定更好吗?有没有我还没有找到的更干净的方法?
iron-ajax
my-login
响应处理程序
_handleLogin(e) {
if (e.detail.response) {
let loginInfo = e.detail.response;
if (loginInfo.o_error) {
console.log('login error: '+loginInfo.o_error);
// ...
} else {
this.dispatch('login', loginInfo); // to polymer-redux store
// UPDATE PATH, OPTION #1
var page = this.ownerDocument.body.children[0];
page.set('route.path', 'server-catalog');
// UPDATE PATH, OPTION #2
this.dispatchEvent(new CustomEvent('change-route', {
bubbles: true, composed: true, detail: "my-todos" }));
// UPDATE PATH, OPTION #3..n
???
}
} else {
console.log(e.detail);
}
}
这两个选项都会触发观察者,_routePageChanged(routeData.page)
,因此魔法继续进行。
选项 #1 很简单,但涉及直接访问父级 my-app。
选项 #2 依赖于对my-app
的两个补充:
ready() {
super.ready();
// Custom elements polyfill safe way to indicate an element has been upgraded.
this.removeAttribute('unresolved');
// listen for custom events
this.addEventListener('change-route', (e)=>this._onChangeRoute(e));
}
_onChangeRoute(e) {
this.set('route.path', e.detail);
}
选项 #2 感觉更好,但我想知道它是否是我能做的最干净的。
建议通过数据绑定将routeData
传递到<my-login>
中,并在_handleLogin()
中设置routeData.page = "my-todos"
我在应用程序位置文档中找到了第三种方法(我想我会使用一种(:"app-location
在更新位置时触发window
location-changed
事件"。所以
window.history.pushState({}, null, '/new_path');
window.dispatchEvent(new CustomEvent('location-changed'));