当用户在浏览器中单击后退按钮并在 Angular 中显示模态时如何捕捉
How can catch when user clicked back button in browser and show modal in Angular
我在处理浏览器中的后退按钮时遇到问题。我有一个自定义模式(只有 html/css,没有 bootstrap),我想在用户单击后退按钮时显示此模式。如果用户选择是,浏览器将直接到上一页。当用户选择否时,模态将消失而不是直接到另一个。我尝试使用 candeactive 和 PlatformLocation,但似乎不起作用。单击时我无法将浏览器直接停止到上一页。有什么解决办法吗?如果是,请给我一个例子。感谢大家的帮助!
这是我的代码:
article.component.html
<div class="editor-page">
<div class="container">
<div class="row">
<div class="col-md-8 offset-md-2">
<form [formGroup]="articleForm" (ngSubmit)="handleSubmit()">
<div class="form-group">
<input type="text" name="title" class="form-control" placeholder="Article Title" formControlName="title">
</div>
<div class="form-group">
<input type="text" name="body" class="form-control" placeholder="What's this article about?" formControlName="body">
</div>
<div class="form-group">
<textarea name="description" class="form-control" id="" cols="30" rows="10" placeholder="Write your article (in markdown)" formControlName="description"></textarea>
</div>
<div class="form-group">
<input type="text" name="tagList" class="form-control" placeholder="Enter tags" formControlName="tagList">
</div>
<button class="btn btn-md btn-success float-right">Publish Article</button>
</form>
</div>
</div>
</div>
</div>
<div class="modal" *ngIf="isBackClicked">
<p>Do you want to quite?</p>
<a (click)="handleYesBtn()">Yes</a>
<a (click)="handleNoBtn()">No</a>
</div>
article.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { ArticleService } from '../../services/article.service';
import { ArticlePost } from '../../models/article';
import { Location } from "@angular/common";
import { Subscription } from 'rxjs/Subscription';
import { PlatformLocation } from '@angular/common'
import { Router } from '@angular/router';
@Component({
selector: 'app-article',
templateUrl: './article.component.html',
styleUrls: ['./article.component.scss']
})
export class ArticleComponent implements OnInit {
isBackClicked = false;
articleForm: FormGroup;
subscription: Subscription;
constructor(
private formBuilder: FormBuilder,
private articleService: ArticleService,
private router: Router,
private location: PlatformLocation
) {
this.articleForm = this.formBuilder.group({
title: "",
body: "",
description: "",
tagList: null
})
location.onPopState(() => {
this.isBackClicked = true;
});
}
ngOnInit() {
}
handleYesBtn() {
this.router.navigateByUrl('/');
}
handleNoBtn() {
this.isBackClicked = false;
}
handleSubmit() {
const article = new ArticlePost(this.articleForm.value);
this.articleService.addArticle(article).subscribe(data => {
console.log('data', data);
})
}
}
当我在浏览器中单击后退按钮时,它没有显示我的模式而是直接返回到上一页。
根据 angular.io,您可以为这种用途创建一个 CanDeactivate
守卫。
我从一个简单的例子开始,它有两条路线,有两个组件 HelloComponent
和 ByeComponent
。要离开 HelloComponent
,将显示一个确认对话框。
首先我从 angular.io 示例中复制了 CanDeactivateGuard
:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
然后我将CanDeactivate
添加到需要确认的组件路由中:
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: HelloComponent, canDeactivate: [CanDeactivateGuard] }
])
],
exports: [RouterModule]
})
export class HelloRoutingModule { }
终于在相关组件中实现了canDeactivate
功能:
canDeactivate() {
return confirm('Are you sure you want to leave Hello ?');
}
您可以使用 HostListener 来处理浏览器的后退按钮
import { HostListener } from '@angular/core';
@HostListener('window:popstate', ['$event'])
onPopState(event) {
console.log('Back button pressed');
//Here you can handle your modal
}
我在处理浏览器中的后退按钮时遇到问题。我有一个自定义模式(只有 html/css,没有 bootstrap),我想在用户单击后退按钮时显示此模式。如果用户选择是,浏览器将直接到上一页。当用户选择否时,模态将消失而不是直接到另一个。我尝试使用 candeactive 和 PlatformLocation,但似乎不起作用。单击时我无法将浏览器直接停止到上一页。有什么解决办法吗?如果是,请给我一个例子。感谢大家的帮助!
这是我的代码:
article.component.html
<div class="editor-page">
<div class="container">
<div class="row">
<div class="col-md-8 offset-md-2">
<form [formGroup]="articleForm" (ngSubmit)="handleSubmit()">
<div class="form-group">
<input type="text" name="title" class="form-control" placeholder="Article Title" formControlName="title">
</div>
<div class="form-group">
<input type="text" name="body" class="form-control" placeholder="What's this article about?" formControlName="body">
</div>
<div class="form-group">
<textarea name="description" class="form-control" id="" cols="30" rows="10" placeholder="Write your article (in markdown)" formControlName="description"></textarea>
</div>
<div class="form-group">
<input type="text" name="tagList" class="form-control" placeholder="Enter tags" formControlName="tagList">
</div>
<button class="btn btn-md btn-success float-right">Publish Article</button>
</form>
</div>
</div>
</div>
</div>
<div class="modal" *ngIf="isBackClicked">
<p>Do you want to quite?</p>
<a (click)="handleYesBtn()">Yes</a>
<a (click)="handleNoBtn()">No</a>
</div>
article.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { ArticleService } from '../../services/article.service';
import { ArticlePost } from '../../models/article';
import { Location } from "@angular/common";
import { Subscription } from 'rxjs/Subscription';
import { PlatformLocation } from '@angular/common'
import { Router } from '@angular/router';
@Component({
selector: 'app-article',
templateUrl: './article.component.html',
styleUrls: ['./article.component.scss']
})
export class ArticleComponent implements OnInit {
isBackClicked = false;
articleForm: FormGroup;
subscription: Subscription;
constructor(
private formBuilder: FormBuilder,
private articleService: ArticleService,
private router: Router,
private location: PlatformLocation
) {
this.articleForm = this.formBuilder.group({
title: "",
body: "",
description: "",
tagList: null
})
location.onPopState(() => {
this.isBackClicked = true;
});
}
ngOnInit() {
}
handleYesBtn() {
this.router.navigateByUrl('/');
}
handleNoBtn() {
this.isBackClicked = false;
}
handleSubmit() {
const article = new ArticlePost(this.articleForm.value);
this.articleService.addArticle(article).subscribe(data => {
console.log('data', data);
})
}
}
当我在浏览器中单击后退按钮时,它没有显示我的模式而是直接返回到上一页。
根据 angular.io,您可以为这种用途创建一个 CanDeactivate
守卫。
我从一个简单的例子开始,它有两条路线,有两个组件 HelloComponent
和 ByeComponent
。要离开 HelloComponent
,将显示一个确认对话框。
首先我从 angular.io 示例中复制了 CanDeactivateGuard
:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
然后我将CanDeactivate
添加到需要确认的组件路由中:
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: HelloComponent, canDeactivate: [CanDeactivateGuard] }
])
],
exports: [RouterModule]
})
export class HelloRoutingModule { }
终于在相关组件中实现了canDeactivate
功能:
canDeactivate() {
return confirm('Are you sure you want to leave Hello ?');
}
您可以使用 HostListener 来处理浏览器的后退按钮
import { HostListener } from '@angular/core';
@HostListener('window:popstate', ['$event'])
onPopState(event) {
console.log('Back button pressed');
//Here you can handle your modal
}