当用户在浏览器中单击后退按钮并在 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 守卫。

我从一个简单的例子开始,它有两条路线,有两个组件 HelloComponentByeComponent。要离开 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 ?');
}

Here is the link for the running example.

您可以使用 HostListener 来处理浏览器的后退按钮

 import { HostListener } from '@angular/core';

@HostListener('window:popstate', ['$event'])
  onPopState(event) {
    console.log('Back button pressed');
    //Here you can handle your modal
  }