In this tutorial we are going to learn how we can to configure an exit guard in the Angular 2 Router. We are going to learn how to use a CanDeactivate route guard to ask the user if he really wants to exist the screen, giving the user to for example save data that was not yet persisted.

What 'canDeactivate' do is for example, you are editing a form, and you click other page by mistake, system will show a confirm dialog to ask whether you want to stay this page.

So first, add input box in hero component, when you type something and press enter, will edit the 'editing' variable to 'true', then we use this variable to control.

import {
Component,
OnInit,
OnDestroy,
ViewChild,
} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {StarWarsService} from "../heros.service";
import {Observable, Subscription} from "rxjs"; @Component({
selector: 'app-hero',
templateUrl: 'hero.component.html',
styleUrls: ['hero.component.css']
})
export class HeroComponent implements OnInit, OnDestroy { @ViewChild('inpRef') input; heroId: number;
hero: Observable<any>;
description: string;
querySub: Subscription;
editing: boolean = false; constructor(private route: ActivatedRoute,
private router: Router,
private starwarService: StarWarsService) {
} ngOnInit() {
this.hero = this.route.params
.map((p:any) => {
this.editing = false;
this.heroId = p.id;
return p.id;
})
.switchMap( id => this.starwarService.getPersonDetail(id)); /* // since herocomponent get init everytime, it would be better to use snapshot for proferemence
this.heroId = this.route.snapshot.params['id'];
this.hero = this.starwarService.getPersonDetail(this.heroId);*/ this.querySub = this.route.queryParams.subscribe(
param => this.description = param['description']
); console.log("observers", this.route.queryParams['observers'].length)
} ngOnDestroy() {
this.querySub.unsubscribe()
} saveHero(newName){
this.editing = true;
console.log("editing", this.editing)
} prev(){
return Number(this.heroId) - ;
} next(){
return Number(this.heroId) + ;
}
}

Because now, from our hero compoennt, we can navigate to other hero component, so snapshot is not ideal for this case, we need to use router.params.

<div>
<h2>{{description}}: {{(hero | async)?.name}}</h2>
<div>
<a [routerLink]="['/heros', prev()]">Previous</a>
<a [routerLink]="['/heros', next()]">Next</a>
</div>
<div>
<input type="text" #inpRef (keyup.enter)="saveHero(inpRef.value)">
</div>
<br>
<img src="{{(hero | async)?.image}}" alt="">
<div>
<a [routerLink]="['/heros']">Back</a>
</div>
</div>

CanDeactivateHero.ts:

import {CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router";
import {Observable} from "rxjs";
import {HeroComponent} from "./hero/hero.component";
export class CanHeroDeactivate implements CanDeactivate<HeroComponent>{
canDeactivate(component: HeroComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean>|boolean { if(!component.editing){
return true;
} return confirm('You have unsaved message, are you sure to leave the page?')
} }

Heros.router.ts:

import {HerosComponent} from "./heros.component";
import {RouterModule} from "@angular/router";
import {HeroComponent} from "./hero/hero.component";
import {CanHeroDeactivate} from "./CanDeactiveHero.directive";
const routes = [
{path: '', component: HerosComponent},
{path: ':id', component: HeroComponent, canDeactivate: [CanHeroDeactivate]},
];
export default RouterModule.forChild(routes)

heros.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HerosComponent } from './heros.component';
import herosRoutes from './heros.routes';
import {HeroComponent} from "./hero/hero.component";
import {StarWarsService} from "./heros.service";
import {RouterModule} from "@angular/router";
import {CanHeroDeactivate} from "./CanDeactiveHero.directive"; @NgModule({
imports: [
CommonModule,
herosRoutes
],
declarations: [HerosComponent, HeroComponent],
providers: [StarWarsService, CanHeroDeactivate]
})
export default class HerosModule { }

Github

[Angular2 Router] CanDeactivate Route Guard - How To Confirm If The User Wants To Exit A Route的更多相关文章

  1. [Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard

    In this tutorial we are going to learn how we can to configure an can activate route guard in the An ...

  2. [Angular2 Router] Resolving route data in Angular 2

    From Article: RESOLVING ROUTE DATA IN ANGULAR 2 Github If you know Anuglar UI router, you must know ...

  3. [Angular2 Router] Exiting an Angular 2 Route - How To Prevent Memory Leaks

    In this tutorial we are going to learn how we can accidentally creating memory leaks in our applicat ...

  4. [Angular2 Router] Optional Route Query Parameters - The queryParams Directive and the Query Parameters Observable

    In this tutorial we are going to learn how to use the Angular 2 router to pass optional query parame ...

  5. [Angular2 Router] Configuring a Home Route and Fallback Route - Learn An Essential Routing Concept

    In this tutorial we are going to learn how to configure the Angular 2 router to cover some commonly ...

  6. [Angular2 Router] Guard: CanLoad

    'canLoad' guard can decide whether a lazy load module can be loaded or not. @Injectable() export cla ...

  7. [Angular2 Router] Load Data Based on Angular 2 Route Params

    You can load resource based on the url using the a combination of ActivatedRouteand Angular 2’s Http ...

  8. [Angular2 Router] Configure Auxiliary Routes in the Angular 2 Router - What is the Difference Towards a Primary Route?

    In this tutorial we are going to learn how we can can configure redirects in the angular 2 router co ...

  9. Angular2 Router路由相关

    路由设置 Angular中路由的配置应该按照先具体路由到通用路由的设置,因为Angular使用先匹配者优先的原则. 示例: 路由设置如下: export const reportRoute: Rout ...

随机推荐

  1. 《学习OpenCV》中求给定点位置公式

    假设有10个三维的点,使用数组存放它们有四种常见的形式: ①一个二维数组,数组的类型是CV32FC1,有n行,3列(n×3) ②类似①,也可以用一个3行n列(3×n)的二维数组 ③④用一个n行1列(n ...

  2. 初学JavaScript(入门一)

    javaScript是世界上最流行的脚本语言   在我们的手机.电脑设备上所浏览的所有网页,以及基于HTML5手机App的交互都是通过javaScript驱动的,所以javascript是前端工作的一 ...

  3. ansible官方文档翻译之变量

    Ansible变量 在使用ansible变量的时候,主要是因为各个系统的不同,从而需要使用不同的变量来进行设置,例如在设置一些配置文件的时候,有大部分内容是相同的,但是一部分内容是和主机的ip地址或者 ...

  4. arp spoofing

    Today our tutorial will talk about Kali Linux Man in the Middle Attack. How to perform man in the mi ...

  5. Linux_系统信息

    公司里一些仿真软件得进Linux系统,好奇公司用的什么Linux版本,于是搜罗了几个命令如下: 1  uname - Print system info -a, print all info -s, ...

  6. 《Java数据结构与算法》笔记-CH4-5不带计数字段的循环队列

    第四章涉及三种数据存储类型:栈,队列,优先级队列 1.概括:他们比数组和其他数据存储结构更为抽象,主要通过接口对栈,队列和优先级队列进行定义.这些 接口表明通过他们可以完成的操作,而他们的主要实现机制 ...

  7. matlab 画锥体

    >> plot3(x,y,z); >> [x,y,z]=cylinder([ ],)

  8. Android问题-XE5提示"[DCC Fatal Error] Project1.dpr(1): F1027 Unit not found: 'System.pas' or binary equivalents (.dcu/.o)"

    问题现象:Checking project dependencies...Compiling Project1.dproj (Debug, Android)dcc command line for & ...

  9. UVA 624 (0 1背包 + 打印路径)

    #include<stdio.h> #include<string.h> #include<stdlib.h> #include<ctype.h> #i ...

  10. Python基础 字符串的魔法

    capitalize(self) 返回值:将字符串的第一个首字母变成大写,其他字母变小写 s = 'hello World' ss = s.capitalize() print(ss) Hello w ...