Angular 2 RC5在canDeactivate中获得预期的路线 [英] Angular 2 RC5 get intended route in canDeactivate

查看:72
本文介绍了Angular 2 RC5在canDeactivate中获得预期的路线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在Angular 2 RC5路由器的CanDeactivate保护中获得预期的路由?我看到了一个有关CanActivate( CanActivate )的类似问题的答案,但是在CanDeactivate保护中似乎不起作用. >

我的用例如下: 用户在填写由"FormComponent"服务的表单的中间时,单击主页"链接. FormComponent附加有CanDeactivate.我需要知道用户正在尝试专门转到家庭"路线来确定我要在CanDeactivate中执行的操作.对CanDeactivate保护中的ActivatedRouteSnapshot和RouterStateSnapshot对象的检查仅显示有关用户当前所处与FormComponent相关的路由的信息.尽管我知道这将两个组件结合在一起,但是这里仅是一个示例,以了解是否可以做到这一点.

解决方案

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

在检查了防护后,我们会触发检查组件中的更改的情况,并向防护返回"已过滤可观察到的". (仅将其过滤为"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,但是为了完整起见,您会在 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) { }
 

Is it possible to get the intended route in the CanDeactivate guard in Angular 2 RC5 router? I see an answer to a similar question about CanActivate (CanActivate), but that does not seem to work in the CanDeactivate guard.

The use case I have is as follows: User clicks on a "Home" link while in the middle of filling out a form serviced by a "FormComponent". The FormComponent has a CanDeactivate attached to it. I need to know that the user was attempting to go specifically to the "Home" route to decide on what I want to do in the CanDeactivate. Inspection of the ActivatedRouteSnapshot and RouterStateSnapshot objects in the CanDeactivate guard only show information about the route that the user is currently on, related to the FormComponent. Although I understand this couples the two components together, this is just an example here to understand whether this is possible to do.

解决方案

You might not need the destination URL for the next route since you can return an Observable<boolean> to the CanDeactivate() in the guard.

When our guard is checked we trigger our check for changes in the component and return a filtered Observable back to the guard. (Filter it for just the "true" value - otherwise we won't be able to continue the navigation to our desired route afterwards!)

When our check passes, we may navigate - if not we can't.

So we maybe want to show our user two buttons. One to skip saving and navigate (doNotSaveAndNavigate()) and another one to save and continue his navigation (doSaveAndNavigate()).. or any other help to guide him or her..

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

(I guess you know how to setup the CanDeactivate for the Router but for the sake of completeness you'll find a usage example in the official docs)


FYI: If you rly just want to get the URL on CanDeactivate() failure, subscribe to the router.events and filter for the NavigationCancel event like this:

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

you may need to import:

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

and add the router to your constructor:

  constructor(private router: Router) { }

这篇关于Angular 2 RC5在canDeactivate中获得预期的路线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆