我有一个应用程序,其路由如下:
/:partner/login
/:partner/tools
/:partner/other
目前使用2.0.0-rc.5
,我可以非常简单地构建完全如上所述的路线。但是,这种方法的缺点是每个组件都必须自己提取partner
参数。所以login
路径声明如下:
{
path: ':partner/login',
component: LoginComponent
}
LoginComponent
看起来像是:
export class LoginComponent implements OnInit {
partner: string;
constructor(private _route: ActivatedRoute) { }
ngOnInit() {
this._route.params.forEach(p => {
this.partner = p[`partner`];
});
}
}
虽然这可以通过3条路线进行管理,但从概念上讲,我真正想说的是我的PartnerComponent
有子路由login
,tools
等。
路由看起来像这样:
{ path: ':partner', component: PartnerComponent
children: [
{ path: 'login', component: LoginComponent},
{ path: 'tools', component: ToolsComponent}
]
}
使用TypeScript的继承,我可以为每个子项创建一个基本组件,如:
export class BaseComponent implements OnInit {
partner: string;
constructor(private _route: ActivatedRoute) { }
ngOnInit() {
this._route.parent.params.forEach(p => {
this.partner = p[`partner`];
});
}
}
和子组件看起来像:
export class LoginComponent extends BaseComponent {
constructor(route: ActivatedRoute) {
super(route);
}
ngOnInit() {
super.ngOnInit();
}
}
虽然上述方法有效,但查找父路线感觉有点脏。我知道如果我改变了层次结构,我只需要在基础中更改它,但仍然是
是否有更简洁的方式在父路由组件之间共享信息。
如果它是更传统的父元素/子元素关系,我们只需使用两者之间的数据绑定来传递该信息。
答案 0 :(得分:1)
您可以做的是为您的父路线使用Resolve
防护,因此将为任何:partner
路线加载数据。
Resolve
看起来像是:
import { Injectable } from '@angular/core';
import { Router, Resolve,
ActivatedRouteSnapshot } from '@angular/router';
import { Partner } from './partner.model';
import { Api } from './api.service';
@Injectable()
export class PartnerResolve implements Resolve<Partner> {
constructor(private api: Api,
private router: Router) {}
resolve(route: ActivatedRouteSnapshot): Observable<Partner> {
let id = +route.params['partner'];
return this.api.getPartner(id);
}
}
然后,您的路线需要包含PartnerResolve
,因此在请求数据并且可用之前不会加载:
{
path: ':partner', component: PartnerComponent,
resolve: {
partner: PartnerResolve
},
children: [
{ path: 'login', component: LoginComponent},
{ path: 'tools', component: ToolsComponent},
]
}
而你的PartnerComponent
只会得到它:
ngOnInit() {
this.route.data.forEach((data: { partner: Partner }) => {
this.partner = data.partner;
});
}
您的子组件将使用:
ngOnInit() {
this.route.parent.data.forEach((data: { partner: Partner }) => {
this.partner = data.partner;
});
}
答案 1 :(得分:-1)
将数据从父级传递给子级的另一种方法是使用@Input
。
@Component({
selector: 'partner',
template: 'partner.html'
directives: [LoginComponent]
})
export class PartnerComponent {
partner: string;
}
@Component({
selector: 'login',
template: 'login.html'
})
export class LoginComponent {
@Input() loginPartner: string; //passed in from the parent
}
//partner.html
<div>
<login [login-partner]='partner'></login>
</div>
参考https://angular.io/docs/ts/latest/cookbook/component-communication.html