簡體   English   中英

實施CanDeactivate Guard時出錯

[英]Error while implementing CanDeactivate Guard

我目前正在嘗試為我的角度應用程序實現CanDeactivate Guard,該應用程序已經具有HTTP攔截器來解析身份驗證。 但是添加CanDeactivate防護會引發錯誤,如下所述。

我已經在AppModule的providers數組中注冊了實現CanDeactivate接口的Class。 我已經在路由的canDeactivate屬性中注冊了實現CanDeactivate接口的類。

實現CanDeactivate接口的類:

export interface CanComponentDeactivate {
  canComponentDeactivate(): boolean;
}

@Injectable({providedIn: 'root'})
export class AppRegisterDeactivateGuard implements CanDeactivate<AppRegisterComponent> {
  canDeactivate(
    component: AppRegisterComponent,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {
    return component.isDeactivated;
  }
}

應用了停用保護的組件:

@Component({
  selector: 'app-app-register',
  templateUrl: './app-register.component.html',
  styleUrls: ['./app-register.component.css']
})
export class AppRegisterComponent implements OnInit, CanComponentDeactivate {
  isDeactivated = false;
  @ViewChild('registrationForm') registForm: NgForm;
.
.
canComponentDeactivate() {
    if (this.registForm.dirty) {
      this.isDeactivated = confirm('You have modified changes in the form. \nDo you still want to navigate away ? ');
    }
    return this.isDeactivated;
  }
}

該端點的路由定義:

...
{ path: 'register', component: AppRegisterComponent, canDeactivate: ['AppRegisterDeactivateGuard'] },

模塊中的Providers數組:

 providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: AppAuthInterceptService,
    multi: true
  }, AppRegisterDeactivateGuard],
  bootstrap: [AppComponent]

錯誤

  StaticInjectorError(Platform: core)[AppRegisterDeactivateGuard]: 
    NullInjectorError: No provider for AppRegisterDeactivateGuard!
Error: StaticInjectorError(AppModule)[AppRegisterDeactivateGuard]: 
  StaticInjectorError(Platform: core)[AppRegisterDeactivateGuard]: 
    NullInjectorError: No provider for AppRegisterDeactivateGuard!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:8896)
    at resolveToken (core.js:9141)
    at tryResolveToken (core.js:9085)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8982)
    at resolveToken (core.js:9141)
    at tryResolveToken (core.js:9085)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8982)
    at resolveNgModuleDep (core.js:21218)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:21907)
    at getToken (router.js:2865)
    at resolvePromise (zone.js:831)
    at resolvePromise (zone.js:788)
    at zone.js:892
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17290)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
    at drainMicroTaskQueue (zone.js:601)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:502)
    at invokeTask (zone.js:1744)

TLDR; 將您的路線更改為此:

{ path: 'register', component: AppRegisterComponent, canDeactivate: [AppRegisterDeactivateGuard] }

將您的提供程序更改為此:

[{
    provide: HTTP_INTERCEPTORS,
    useClass: AppAuthInterceptService,
    multi: true
  }]

更長的答案:

不需要同時具有{providedIn: 'root'}和將其聲明為模塊中的提供者的AppRegisterDeactivateGuard。 請參閱Angular提供程序文檔

這里的問題是路由和提供者的結合。

現在,您的路線正在通過字符串名稱查找令牌,但是可以通過類名稱使用。

如何使用@Injectable({providedIn: 'root'})將類名用作令牌,它將以AppRegisterDeactivateGuard形式提供。

AppRegisterDeactivateGuard在你的供應商,你怎么會有這將使其可作為AppRegisterDeactivateGuard。

我不建議這樣做,但是如果您希望或需要通過字符串名稱引用它,則可以將其放在提供程序中,如下所示:

{ provide: 'AppRegisterDeactivateGuard', useClass: AppRegisterDeactivateGuard }

您需要以泛型形式傳遞接口:

export class AppRegisterDeactivateGuard implements CanDeactivate<CanComponentDeactivate > {

然后實現canDeactivate方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM