2017-01-26 55 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> { } 

你仍然需要把兩者在供應商列表中,這樣它並沒有變成儘可能簡化得如我所願 - 但如果您還需要以其他方式擴展您的警惕邏輯,那麼這可能是一種很好的模式。

相關問題