首页 文章

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

提问于
浏览
1

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

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

2 回答

  • 0

    您可能不需要下一个路由的目标URL,因为您可以将 Observable<boolean> 返回到防护中的 CanDeactivate() .

    检查我们的防护后,我们会触发检查组件中的更改并将 filtered 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...
      }
    }
    

    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;
      }
    }
    

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


    仅供参考:如果您只想在 CanDeactivate() 失败时获得 URL ,请订阅 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) { }
    
  • 3

    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 .

相关问题