在Angular2中,是否可以使用相同的防护(例如CanActivate或CanDeactivate),它可以应用于多个组件?
这是MyComponent1
的守卫:
@Injectable()
export class MyGuard implements CanDeactivate<MyComponent1> {
canDeactivate(component: MyComponent1): Promise<boolean> {
// my code here
}
}
我想要MyComponent2
,MyComponent3
等完全相同的保护。
我该如何实现?我需要按组件声明一个新的防护类,还是可以重用我的班级MyGuard
?
答案 0 :(得分:4)
只需将相同的防护添加到您希望应用它的每条路线。
或者,您也可以创建无组件父路线,在其中添加防护,并且所有子路线将受同一防护保护。 这仅在组件全部处于同级路由时才有效。
Angular DI不支持泛型类型参数。作为一种解决方法,这应该做你想要的(事件虽然可能比你想要的更冗长):
routes: [
{ path: 'x', component: MyComponent1, canDeactivate: [new Inject('CanDeactivateMyComponent1') },
{ path: 'y', component: MyComponent2, canDeactivate: [new Inject('CanDeactivateMyComponent2') },
]
@NgModule({
providers: [
{provide: 'CanDeactivateMyComponent1', useFactory: () => new CanDeactivate<MyComponent1>()},
{provide: 'CanDeactivateMyComponent2', useFactory: () => new CanDeactivate<MyComponent2>()},
],
})
export class AppModule {}
...
})
答案 1 :(得分:2)
路线:
routes: [
{ path: 'x', component: MyComponent1, canDeactivate: ['MyGuard '] },
{ path: 'y', component: MyComponent2, canDeactivate: ['MyGuard '] },
]
守卫:
@Injectable()
export class MyGuard implements CanDeactivate<MyComp1 | MyComp2> {
constructor() { }
canDeactivate(
component: PermissionSetsComponent | NodeAccessGroupComponent,
): Observable<boolean> | Promise<boolean> | boolean {
// Your code here
}
}
答案 2 :(得分:1)
基于Günter Zöchbauer's answer,我有一个解决方案。
后卫:
@Injectable()
export class MyGuard<T> implements CanDeactivate<T> {
// Maybe some DI here, just inject them into useFactory and deps
constructor() {}
canDeactivate(component: T): Promise<boolean> {
// my code here
}
}
只是提供你的警卫:
routes: [
{ path: 'x', component: MyComponent1, canDeactivate: ['CanDeactivateMyComponent1'] },
{ path: 'y', component: MyComponent2, canDeactivate: ['CanDeactivateMyComponent2'] },
]
@NgModule({
providers: [
{provide: 'CanDeactivateMyComponent1', useFactory: () => new MyGuard<MyComponent1>()},
{provide: 'CanDeactivateMyComponent2', useFactory: () => new MyGuard<MyComponent2>()},
],
})
export class AppModule {}
...
})
答案 3 :(得分:0)
它只是冗长而另一种选择是使用继承来创建一个新的专业守卫。
我的通用后卫看起来像这样:
// this goes on the component itself
export interface IUnsavedChangesComponent
{
hasUnsavedChanges(): boolean;
}
@Injectable()
export class SaveFormsGuard<C extends IUnsavedChangesComponent> implements CanDeactivate<C>
{
constructor()
{
console.log("SAVEFORMSGUARD");
}
canDeactivate(component: C)
{
var hasUnsavedChanges = component.hasUnsavedChanges();
... dialog box logic ...
return !hasUnsavedChanges;
}
}
所以我创造了新的警卫
export class SaveFormsGuard_OrderEditor extends SaveFormsGuard<OrderEditorComponent> { }
export class SaveFormsGuard_CustomerEditor extends SaveFormsGuard<CustomerEditorComponent> { }
你仍然必须将它们都放在提供者列表中,所以它并没有像我希望的那样简单 - 但如果你还需要扩展逻辑,可能是一个很好的模式以其他方式守护你。