【问题标题】:Angular 8 Cancel or do something before navigation startsAngular 8在导航开始之前取消或做某事
【发布时间】:2019-10-08 18:53:01
【问题描述】:

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

<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');
  ) {}

编辑

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

这是我的用例。

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

编辑 2

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

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

RouterModule.forRoot([
  {
    path: 'team/:id',
    component: TeamComponent,
    canDeactivate: ['canDeactivateTeam']
  }

我不想在每条路线上都有 CanDeactivate,当只有 1 条路线时 里面有foo 组件。

路由很多,只有一个路由需要foo组件,需要可以取消路由导航。据我所知,canDeactivate 路由 gaurd 无法访问在路由上创建的组件。

编辑 3

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

【问题讨论】:

  • 这是在组件的外部完成的。您正在寻找路线守卫。
  • NavigationStart的Router事件怎么样?
  • 另外我认为你的意思是写组件而不是控制器。
  • 另请参阅angular.io/guide/router#canactivate-requiring-authentication 作为如何执行此操作的示例。
  • “我不希望通过 Route Guard 完成此操作”。为什么?这基本上就是 CanDeactivate 守卫存在的目的。您绝对可以轻松地将它用于您的用例。

标签: angular typescript


【解决方案1】:

没有其他方法可以防止在没有 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
  }
}

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

所以像上面一样保护并在路由中设置canDeactivate:

{
    path: 'team/:id',
    component: TeamComponent,
    canDeactivate: [DeactivateGuard]
}

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

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

假设,有时 foo 组件会在 TeamComponent 中。就在 foo 组件中:

export class FooComponent implements OnInit {

  constructor(private deactGuard: DeactivateGuard) { }

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

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

}

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

【讨论】:

  • 这似乎是我需要的一个很好的答案。你能告诉我这条路线是什么样子的吗?我将如何把它连接起来?如果不是那也很酷,我可以尝试弄清楚
  • @gh9 是的,我可以。
  • 很好,非常感谢!先生,您应该得到更多的支持,希望这个问题能为您带来更多。
  • @gh9 已更新。不要认为会产生更多。
  • 不用担心,我可以从这里开始工作,非常感谢!
【解决方案2】:

根据以下评论进行编辑: 一种可能的解决方案如下: 将 X.component.html 更改为:

<a (click)='goToCrisisCenter()' routerLinkActive="active">Crisis Center</a>

X.component.ts

constructor(private navigationService: NavigationService) {}

goToCrisisCenter() {
  this.navigationService.tryNavigateTo('/crisis-center');
}

使用以下命令创建 NavigationService:

canNavigate = true;
tryNavigateTo(route:string) {
  if(canNavigate) this.router.navigate([/crisis-center])
}

在 HeroListComponent 中注入 NavigationService 并根据需要操作 canNavigate。

【讨论】:

  • 路由不在组件上它在另一个组件上,如果它在同一个组件上,你将 100% 准确。
  • @gh9 我已经重写了我的答案来涵盖这一点。
  • @SimonKazakov 他将需要更改整个导航系统 = 不再使用 routerLink="" 任何地方。
  • 在 AppModule.ts providers: [{ provide: Router, useClass: CrisisCenter,}] 大声笑。 XD
【解决方案3】:

试试这个:

import { Router } from '@angular/router';


export class HeroListComponent implements OnInit {
 cancelRoute : boolean = true

  constructor(provate router: Router) {
   if (cancelRoute) {
     this.router.navigate(["/yourRoute"]);
   } else {
     this.router.navigate(["/yourRouteElse"]); 
   }
}
// If you don't want me to do something the `else`, leave it empty.

我给你留了一份文件: https://www.techiediaries.com/angular-router-routerlink-navigate-navigatebyurl/

【讨论】:

  • 这不会取消路线,只是导航到其他地方。请用英文发布答案,因为 SO 是一个仅限英文的网站。
  • 这里是 SO 西班牙语网站的链接。 es.stackoverflow.com
  • 戈麦斯先生请用英文写。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 2013-03-03
  • 2014-03-27
  • 1970-01-01
  • 2014-04-25
  • 1970-01-01
相关资源
最近更新 更多