Angular 单击“浏览器后退/前进”时角度更新内容

Angular 单击“浏览器后退/前进”时角度更新内容,angular,typescript,rxjs,angular5,observable,Angular,Typescript,Rxjs,Angular5,Observable,除了问题的标题,我已经在Angular 5中编写了一个实现来实现这一点,但是我没有使它工作 其想法是,每当用户在浏览器中单击后退或前进时,应用程序都能够检测url的更改,并在内容仍在同一组件中时更新内容 import { Component, OnInit } from '@angular/core'; import { Location, PopStateEvent } from '@angular/common'; import { ActivatedRoute, Event, Navig

除了问题的标题,我已经在Angular 5中编写了一个实现来实现这一点,但是我没有使它工作

其想法是,每当用户在浏览器中单击后退或前进时,应用程序都能够检测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!

我理解由于PopStateEvent change detect内的多个subscribe,我会被累积解雇,但我正在努力找到一个解决方法来实现我想要的行为。

因为您没有取消订阅
路由器.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();

          }
        });
      }
    });

它现在工作得很好。(确保在新窗口中打开输出)

我发誓在发布之前我已经尝试过你的尝试,但现在它对我有效!