Угловое обновление содержимого при нажатии браузера вперед / назад - PullRequest
0 голосов
/ 31 мая 2018

В дополнение к названию вопроса я написал реализацию в Angular 5 для достижения этой цели, однако мне не удалось заставить ее работать.

https://stackblitz.com/edit/angular-nhtgbr

Идея заключается в том, что каждый раз, когда пользователь нажимаетназад или вперед в своем браузере, приложение может обнаружить изменения URL и обновить содержимое, если оно все еще находится в том же компоненте.

import { Component, OnInit } from '@angular/core';
import { Location, PopStateEvent } from '@angular/common';
import { ActivatedRoute, Event, NavigationEnd, Router } from '@angular/router';

@Component({
  selector: 'app-dashboard',
  template: 'Read in console'
})
export class DashboardComponent implements OnInit {

  page: number = 1;

  constructor(private router: Router,
    private activatedRoute: ActivatedRoute,
    private location: Location) { }

  ngOnInit() {

    this.detectPopState();

    setTimeout(() => this.goToPage(1), 1000);
    setTimeout(() => this.goToPage(2), 2000);
    setTimeout(() => this.goToPage(3), 3000);
    setTimeout(() => this.goToPage(4), 4000);
    setTimeout(() => window.history.back(), 5000);  // will trigger location PopStateEvent
    setTimeout(() => window.history.back(), 6000);  // Trigger twice! Expected to trigger only once
    setTimeout(() => window.history.back(), 7000); // Trigger 3 times!
  }

  detectPopState() {
    this.location.subscribe((popStateEvent: PopStateEvent) => {
      // Detect popstate
      if (popStateEvent.type === 'popstate') {
        const eventSubscription = this.router.events.subscribe((event: Event) => {
          if (event instanceof NavigationEnd) {
            this.page = this.activatedRoute.snapshot.queryParams.page;
            this.updateContent();
          }
        });
      }
    });
  }

  updateContent() {
    console.log('Update content ' + this.page);
  }

  goToPage(page: number) {
    this.page = page;
    this.router.navigate(['/dashboard'], {
      queryParams: {
        page: this.page
      }
    });
    this.updateContent();
  }
}

Проблема здесь:

setTimeout(() => window.history.back(), 6000);  // Trigger twice! Expected to trigger only once
setTimeout(() => window.history.back(), 7000); // Trigger 3 times!

Я понимаюupdateContent() кумулятивно увольняется из-за множественных подписок внутри обнаружения изменений PopStateEvent, но я изо всех сил пытаюсь найти обходной путь для достижения желаемого поведения.

1 Ответ

0 голосов
/ 01 июня 2018

Потому что вы не отменили подписку на router.events (наблюдаемая).Итак, у вас закончилась утечка памяти.

Решение:

Отмените подписку на router.events

this.location.subscribe((popStateEvent: PopStateEvent) => {
      if (popStateEvent.type === 'popstate') {
        const eventSubscription = this.router.events.subscribe((event: Event) => {
          if (event instanceof NavigationEnd) {
            this.page = this.activatedRoute.snapshot.queryParams.page;
            this.updateContent();

            // Here it is
            eventSubscription.unsubscribe();

          }
        });
      }
    });

Теперь она работает отлично. Вы можете проверить из Stackblitz .(Обязательно откройте вывод в новом окне)

...