用户单击浏览器中的后退按钮并在Angular中显示模式时如何捕获

时间:2018-07-16 13:34:14

标签: angular angular5 angular6

我在浏览器中有向后手柄按钮的问题。我有一个自定义模式(只是html / css,没有引导程序),我想在用户单击后退按钮时显示此模式。如果用户选择是,浏览器将直接转到上一页。当用户选择“否”时,模态将消失并且不会直接复制到另一个模态。我尝试使用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);
    })
  }

}

当我在浏览器中单击后退按钮时,它没有显示我的模式,而是直接显示到上一页。

2 个答案:

答案 0 :(得分:2)

根据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.

答案 1 :(得分:1)

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

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

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