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

时间:2016-09-11 19:49:39

标签: angular angular2-routing

是否有可能在Angular 2 RC5路由器的CanDeactivate防护中获得预期路由?我看到了关于CanActivate(CanActivate)的类似问题的答案,但这似乎在CanDeactivate后卫中没有用。

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

2 个答案:

答案 0 :(得分:4)

您可能不需要下一个路线的目标网址,因为您可以将Observable<boolean>返回到警卫中的CanDeactivate()

当检查我们的后卫时,我们会触发检查组件中的更改并将过滤的 Observable返回给后卫。 (仅对&#34; true&#34;值进行过滤 - 否则我们无法继续导航到我们想要的路线!)

当我们的支票通过时,我们可能会导航 - 如果不是,我们就可以。

所以我们可能想向用户显示两个按钮。一个要跳过保存并导航(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...
  }
}

可以-停用-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;
  }
}

(我想您知道如何为路由器设置CanDeactivate,但为了完整起见,您将在official docs中找到一个用法示例)

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

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

您可能需要导入:

import { Router, NavigationCancel } from '@angular/router'; 
import 'rxjs/add/operator/filter';

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

  constructor(private router: Router) { }

答案 1 :(得分:1)

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

您可以here看到它。

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

您可以将其与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;

讨论过here