2017-01-26 56 views
2

在Angular2中,是否可以具有相同的警卫(例如CanActivate或CanDeactivate),它可以应用于多个组件?Angular2:如何在多个组件中使用相同的警卫

这里是MyComponent1保护:

@Injectable() 
export class MyGuard implements CanDeactivate<MyComponent1> { 

    canDeactivate(component: MyComponent1): Promise<boolean> { 
    // my code here 
    } 
} 

正是我想要的MyComponent2相同后卫,MyComponent3

我如何能实现呢?我需要按部件声明一个新的守卫类,或者我可以重用我的类MyGuard吗?

回答

2

只需将相同的警卫添加到您希望应用的每条路线。

或者,您也可以创建一个无组件的父路由,您在其中添加警卫,并且所有的子路由将受同一警卫保护。 这只适用于组件全部在同级路线中的情况。

角度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 {} 
    ... 
}) 
+2

我认为@ElJackiste的疑问是关于Guard实现所需的类型。这是一个很好的答案,但也许不是他正在等待的那种答案。 –

+0

具有'CanDeactivate '的事实不会阻止守护类到这个组件'MyComponent1'? – ElJackiste

+1

没有看到通用参数。所以你需要不同的警卫实例,专门用于警卫所应用的组件。您需要提供不同的实例。我会更新我的答案。 –

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 {} 
    ... 
}) 
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> { } 

你仍然需要把两者在供应商列表中,这样它并没有变成尽可能简化得如我所愿 - 但如果您还需要以其他方式扩展您的警惕逻辑,那么这可能是一种很好的模式。

相关问题