Angular 6 - кнопка «Назад» нажимает триггер более одного раза

У меня есть следующий код для обнаружения нажатия кнопки «Назад» с помощью angular 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/… . О решении: вы должны отписаться, когда запускается событие перед выгрузкой браузера. В противном случае ngOnDestroy не будет вызываться, потому что это не прямое угловое уничтожение компонента.

briosheje 08.04.2019 15:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
7
1
2 188
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам просто нужно отписаться, когда компонент будет уничтожен хуком жизненного цикла 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');
      }
    });
  }
}

Как упоминалось в комментариях Бриошейе, хук жизненного цикла не запускается при обновлении браузера. Для этого вам нужно обработать отмену подписки на событие onbeforereload документа.

Разумный ответ, хотя нгондестрой не будет вызываться для обновить. Лучше прослушать событие onbeforeunload с помощью HostListener и вместо этого отписаться там, мне.

briosheje 08.04.2019 15:20

Остерегайтесь обновлений браузера: P

briosheje 08.04.2019 15:33

@briosheje Очень интересно. Не знал, что подписки могут сохранять перезагрузку браузера для некоторых браузеров. Я включил ваш вклад в свой ответ :)

Daniel 08.04.2019 15:38

@briosheje Спасибо, что помните. На самом деле это не было проблемой.

Shijin TR 08.04.2019 15:39

@Daniel на самом деле, цикл angular разрушать никогда не вызывается при обновлении (что вводит в заблуждение, поскольку «уничтожить» с семантической точки зрения следует вызывать всякий раз, когда компонент эффективно уничтожается ...). Обычно это вообще не влияет на какое-либо программное обеспечение, поскольку большинство приложений построены так, чтобы фактически работать из любого состояния, из которого исходит страница... Однако конкретно в этом случае это может немного повлиять на общий цикл. В любом случае, спасибо, что упомянули об этом выше.

briosheje 08.04.2019 15:43

Проблема, которую я проанализировал здесь, заключается в том, что каждый раз, когда запускается конструктор. Он точно вызовет вашу функцию. Таким образом, вы должны проверить, была ли эта функция запущена ранее или нет. Самый простой ответ

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, это зависит от вас, какой способ вы хотите выбрать, насколько мне известно, это самый простой способ.

Другие вопросы по теме