【问题标题】:Angular 6 - Back button press trigger more than onceAngular 6 - 多次按下后退按钮触发
【发布时间】:2019-04-08 13:04:41
【问题描述】:

我有以下代码来检测使用角度 6 的后退按钮按下。

import { Location } from '@angular/common';
export class ProductsComponent implements OnInit {

constructor( private location: Location){
  this.handleBackButtonPress();
}
  handleBackButtonPress() {
    this.subscribed = true;
    this.location.subscribe(redirect => {
     if (redirect.pop === true) {
      alert('this is a backbutton click');
     }
    });
  }
}

这是有效的,我们在按下后退按钮时收到警报。问题是,如果我们多次访问同一个页面,它会触发警报,显示我们访问具有相同组件的路由的次数。

注意: 我已经检查了类似this.location.unsubscribe() 的解决方案,但没有找到类似location 的功能。

【问题讨论】:

  • 关于退订:stackoverflow.com/questions/48729990/… 。关于解决方案:当浏览器的事件 onbeforeunload 被触发时,您应该 unsubscribe。否则,ngOnDestroy 将不会被调用,因为它不会直接从角度破坏组件。

标签: javascript angular typescript


【解决方案1】:

当组件被ngOnDestroy生命周期钩子销毁时,您只需取消订阅即可。

import { Location } from '@angular/common';
import { SubscriptionLike } from 'rxjs';

export class ProductsComponent implements OnInit, OnDestroy {

  public subscription: SubscriptionLike;

  constructor(private location: Location){
    this.handleBackButtonPress();
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  handleBackButtonPress() {
    this.subscription = this.location.subscribe(redirect => {
      if (redirect.pop === true) {
        alert('this is a backbutton click');
      }
    });
  }
}

正如briosheje 在 cmets 中提到的,生命周期挂钩不会在浏览器刷新时运行。为此,您需要处理文档的 onbeforereload 事件的取消订阅。

【讨论】:

  • 合理的响应,虽然 ngOnDestroy 不会在 refresh 时被调用。您应该使用HostListener 收听onbeforeunload 事件,然后取消订阅。
  • 小心浏览器刷新,不过:P
  • @briosheje 非常有趣。不知道订阅可能会持续为某些浏览器重新加载浏览器。我已将您的贡献包含在我的回答中:)
  • @briosheje 感谢您的记忆。实际上,这不是一个问题
  • @Daniel 实际上,角度的 destroy 循环永远不会在刷新时调用(这是误导性的,因为从语义的角度来看,应该在任何时候调用“destroy”该组件被有效地破坏了......)。通常这根本不会真正影响任何软件,因为大多数应用程序都是从页面来自的任何状态实际工作的......但是,特别是对于这种情况,它可能会影响整个周期。无论如何,感谢您在上面提到这一点。
【解决方案2】:

我在这里分析的问题是,每次构造函数都会运行。它肯定会调用你的函数。所以你必须检查这个函数之前是否已经运行过。 最简单的答案是

constructor( private location: Location){
 const PopCalled = localStorage.getItem('PopCalled')
 if(!PopCalled)
  this.handleBackButtonPress();
}

handleBackButtonPress() {
 this.subscribed = true;
  this.location.subscribe(redirect => {
  if (redirect.pop === true) {
  localStorage.setItem('PopCalled', true);
  alert('this is a backbutton click');
  }
 });
}

基本上,您必须管理 PopCalled 的状态,这取决于您要选择哪种方式,据我所知,这是最简单的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    相关资源
    最近更新 更多