Angular 8 在导航开始之前取消或执行某些操作

gh9*_*gh9 6 typescript angular

我有一个场景,我有一条路线

<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>

在控制器中,我想取消基于值的路由导航。

export class HeroListComponent implements OnInit {
 cancelRoute : boolean = true

  constructor(
   //some logic where before the route is navigated to, I want it to cancel the route
   // and log a message to console
   //console.log('successfully, canceled route');
  ) {}
Run Code Online (Sandbox Code Playgroud)

编辑

我不希望通过 Route Guard 完成此操作,我希望在组件级别完成此操作。我的页面上有一个组件,我想取消路线导航。

这是我的用例。

我有一个托管多个组件的页面,如果有人离开该页面,我想检查组件 A 并确保在他们离开之前没有任何未保存的数据。

编辑2

“我不希望通过路线守卫来完成这件事”。为什么?这本质上就是 CanDeactivate 守卫存在的目的。您绝对可以轻松地将它用于您的用例。

如果我错了,请纠正我,但我需要将 CanDeactivateGuard 放在每条路线上

RouterModule.forRoot([
  {
    path: 'team/:id',
    component: TeamComponent,
    canDeactivate: ['canDeactivateTeam']
  }
Run Code Online (Sandbox Code Playgroud)

我不想在每条路线上都有 CanDeactivate,因为只有 1 条路线foo内部有组件。

路线有很多条,只有一条路线需要foo组件,并且他需要可以取消路线导航。据我所知,canDeactivate路由守卫无法访问在路由上创建的组件。

编辑3

NavigationStart文档指出这是一个被触发的事件。我可以挂钩该事件,但我无法停止实际导航。除非我错了,NavigatonStart只是告诉我何时开始导航,而不是如何停止导航。

Mis*_*ses 7

没有其他方法可以阻止在没有 DeactivateGuard 的情况下进行导航,但是!你可以让他成为可注射的。

import { CanDeactivate } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { Injectable } from '@angular/core';

@Injectable()
export class DeactivateGuard implements CanDeactivate<HomeComponent> {

    canDeact = true

  canDeactivate() {
    return this.canDeact
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以将其注入到您想要的任何组件中并更改canDeact为 false,这样您就可以防止在工作未完成时导航到其他路线。不过,默认情况下canDeact为 true,因此如果在您的路线中不会有任何组件foo会触发 ngOnInit,这会使 Guard 为 false 并阻止导航出去。

因此如上所述进行防护并在路由中设置canDeactivate:

{
    path: 'team/:id',
    component: TeamComponent,
    canDeactivate: [DeactivateGuard]
}
Run Code Online (Sandbox Code Playgroud)

因为它是可注入的,所以在某些根模块中提供它:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [
    DeactivateGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

假设有时 foo 组件将位于 TeamComponent 内部。就在 foo 组件中:

export class FooComponent implements OnInit {

  constructor(private deactGuard: DeactivateGuard) { }

  ngOnInit() {
    this.deactGuard.canDeact = false
  }

  jobDone() {
    this.deactGuard.canDeact = true
  }

}
Run Code Online (Sandbox Code Playgroud)

尝试不要将 foo 组件粘贴到 TeamComponent 范围之外。或者在 ngOnInit 中正确开发它,这样他就不会在他想要的时候使 canDeact 为假。