Angular 2 RC5 在 canDeactivate 中获得预期路线

ruk*_*ruk 6 angular2-routing angular

是否可以在 Angular 2 RC5 路由器的 CanDeactivate 防护中获得预期的路线?我看到了一个关于 CanActivate ( CanActivate )的类似问题的答案,但这在 CanDeactivate 守卫中似乎不起作用。

我的用例如下:用户在填写由“FormComponent”服务的表单的过程中单击“主页”链接。FormComponent 有一个 CanDeactivate 附加到它。我需要知道用户正试图专门转到“主页”路线来决定我想在 CanDeactivate 中做什么。检查 CanDeactivate 守卫中的 ActivatedRouteSnapshot 和 RouterStateSnapshot 对象仅显示有关用户当前所在路径的信息,与 FormComponent 相关。虽然我理解这将两个组件耦合在一起,但这只是一个示例,以了解这是否可行。

ben*_*boe 6

您可能不需要下一条路线的目标 URL,因为您可以将 an 返回Observable<boolean>CanDeactivate()守卫中。

当我们的守卫被检查时,我们会触发对组件变化的检查,并将过滤后的Observable 返回给守卫。(仅过滤“true”值 - 否则我们将无法继续导航到我们想要的路线!)

当我们的检查通过时,我们可以导航 - 如果没有,我们就不能。

所以我们可能想向我们的用户展示两个按钮。一个跳过保存和导航 ( doNotSaveAndNavigate()) 另一个保存并继续他的导航 ( doSaveAndNavigate()).. 或任何其他帮助指导他或她..

some.component.ts

import { Component } from '@angular/core';

// Utils
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable }      from 'rxjs/Observable';

@Component({
  selector: 'selector',
  templateUrl: 'some.component.html'
})
export class SomeComponent {
  // Utils
  youMayNavigateSource = new BehaviorSubject<boolean>(false);
  youMayNavigate$: Observable<boolean> = this.youMayNavigateSource.asObservable();

  checkForUnsavedChanges(): void {
    // Check your form/data for changes...
    let hasSaved: boolean = false;
    // Set the next value for our observable
    this.youMayNavigateSource.next(hasSaved);
  }

  canDeactivate(): Observable<boolean> {
    // Do some checking if we "can deactivate" the current route 
    this.checkForUnsavedChanges();
    // Return an observable so we can change it later on and continue our navigation attempt
    return this.youMayNavigate$.filter(el => el); // (!)
  }

  allowNavigation(): void {
    // Set the next value for our observable to true
    this.youMayNavigateSource.next(true);
  }

  doNotSaveAndNavigate(): void {
    this.allowNavigation();
  }

  doSaveAndNavigate(): void {
    // Save our data
    this.doSave();
    this.allowNavigation();
  }

  doSave(): void {
    // do some fancy saving...
  }
}
Run Code Online (Sandbox Code Playgroud)

can-deactivate-guard.service.ts

import { Injectable }    from '@angular/core';
import { CanDeactivate } from '@angular/router';

import { SomeComponent } from './some.component';

@Injectable()
export class CanDeactivateGuard implements CanDeactivate<SomeComponent > {
  canDeactivate(component: SomeComponent ) {
    return component.canDeactivate ? component.canDeactivate() : true;
  }
}
Run Code Online (Sandbox Code Playgroud)

(我猜你知道如何为路由器设置 CanDeactivate 但为了完整起见,你会在官方文档中找到一个使用示例)


仅供参考:如果您只想在失败时获取URLCanDeactivate(),请订阅router.events并过滤NavigationCancel事件,如下所示:

this.router.events
           .filter(event => event instanceof NavigationCancel)
           .subscribe(el => console.log('Requested URL:', el.url));
Run Code Online (Sandbox Code Playgroud)

您可能需要导入:

import { Router, NavigationCancel } from '@angular/router'; 
import 'rxjs/add/operator/filter';
Run Code Online (Sandbox Code Playgroud)

并将其添加router到您的构造函数中:

  constructor(private router: Router) { }
Run Code Online (Sandbox Code Playgroud)


rmc*_*rry 5

Angular 4 向 CanDeactivate 接口引入了一个额外的可选参数。

你可以在这里看到它。

    canDeactivate(
      component: T, 
      currentRoute: ActivatedRouteSnapshot,
      currentState: RouterStateSnapshot, 
      nextState?: RouterStateSnapshot
      ): Observable<boolean>|Promise<boolean>|boolean;
Run Code Online (Sandbox Code Playgroud)

您可以将其与 Observable、Promise 一起使用或立即返回布尔值。

例子:

      canDeactivate(
        component: RetailerComponent,
        route: ActivatedRouteSnapshot,
        currentState: RouterStateSnapshot,
        nextState: RouterStateSnapshot
      ): Observable<boolean> | boolean {
        if (nextState.url.includes('company/manage'))
          return false;
        else
          return true;
Run Code Online (Sandbox Code Playgroud)

这里讨论。