除了问题标题之外,我已经在Angular 5中编写了一个实现来实现这一点但是我没能使它工作。
https://stackblitz.com/edit/angular-nhtgbr
这个想法是每当用户在浏览器中向后或向前点击时,应用程序能够检测到网址更改并更新内容(如果它仍在同一个组件中)。
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更改检测中的多个订阅而被累积激发,但我很难找到解决方法来实现我想要的行为。
答案 0 :(得分:2)
因为您未取消订阅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();
}
});
}
});
它现在完美运作。 You can test from Stackblitz。 (确保在新窗口中打开输出)