我想在我的单页面应用程序(Angular 项目)中使用路由器来检测页面何时刷新。
还有其他方法吗?
在 component.ts 文件中:
import { Subscription } from 'rxjs';
export let browserRefresh = false;
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnDestroy {
subscription: Subscription;
constructor(private router: Router) {
this.subscription = router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
browserRefresh = !router.navigated;
}
});
}
在您需要的页面中:
import { browserRefresh } from '../app.component';
....
ngOnInit() {
this.browserRefresh = browserRefresh;
console.log('refreshed?:', browserRefresh);
}
请参阅工作示例:https://stackblitz.com/edit/refreshangular?file=src%2Fapp%2Fpage-a%2Fpage-a.component.ts
点击A页和B页,刷新看看区别。
试试这个:
this.router.events
.pipe(filter((rs): rs is NavigationEnd => rs instanceof NavigationEnd))
.subscribe(event => {
if (
event.id === 1 &&
event.url === event.urlAfterRedirects
) {
// Your code here for when the page is refreshd
}
})
您需要导入
import { filter } from 'rxjs/operators'
import { Router } from '@angular/router';
Angular 应用程序是单页应用程序,在单页应用程序的上下文中,完整的应用程序加载一次,并且当用户使用您的应用程序时刷新数据或屏幕。
浏览器刷新相当于关闭应用程序并再次启动。在 Angular 应用程序中没有任何默认方式可以对此做出响应。
您也许可以使用 onBeforeUnload() 来模拟某些内容,以记录应用程序已重新加载;然后检查应用程序初始化例程中的日志以执行一些特殊操作。
Angular 7 及更高版本中的最新方法是我们现在可以添加路线导航属性。
因此,如果
/somepage
是我们要检测的页面,并且浏览器已刷新,则当我们转到此页面时,我们设置 navigate 属性 prevPage:
this.router.navigate(['/somepage'], { state: { prevPage: this.router.url } });
然后在某个页面里面:
ngOnInit(): void {
const previousUrl = history.state.prevPage ?? null;
if (!this.previousUrl) {
console.log('page was refreshed!');
} else {
console.log('I came here from: ', previousUrl);
}
}
注意: 如果您想检测特定页面的浏览器刷新,则此方法有效。
如果您在整个网站上都需要这个,那么我会采用不同的方法。
我想使用路由器检测页面何时刷新
您向路由器添加一个顶级解析器。如果您有一个顶级路由器,那么它只会被解析一次,并且子级将处理页面导航。解析器每解析一次就等于浏览器刷新一次页面。
const routes: Routes = [
{
path: '',
component: TopComponent,
resolve: { loaded: PageLoadedResolver },
children: [
...
]
}
];
还有许多其他方法可以在 Angular 中检测页面加载事件。
你的
AppModule
的构造函数。
@NgModule({...})
export class AppModule {
public constructor() {
console.log('page loaded');
}
}
注入根的服务至少使用一次。
@Injector({provideIn: 'root'})
export class MyService {
public constructor() {
console.log('page loaded');
}
}
还有引导 Angular 应用程序的
main.ts
文件。
platformBrowserDynamic().bootstrapModule(AppModule)
.then(() => console.log('page loaded'))
.catch(err => console.error(err));
基本上,任何有 JavaScript 运行一次的地方......
我通常通过检查两个特定的路由器事件来检测页面重新加载。每次浏览器的路径发生变化时,Angular 路由器事件都会从 NavigationStart 开始触发,但是,当页面简单地重新加载时,只会触发结束事件,并且它们从 ActivationEnd 开始触发。
为了能够判断页面是否已重新加载,或者用户是否只是导航到应用程序中的同一位置,我将使用以下代码:
import { Component, inject } from "@angular/core";
import { ActivationEnd, NavigationStart, Router } from "@angular/router";
import { filter, fromEvent, tap } from "rxjs";
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html'
})
export class LayoutComponent {
/* DEPENDENCIES */
private readonly _router = inject(Router);
/* MEMBERS */
constructor() {
let pageReloaded: {
started ? : boolean,
ended ? : boolean
} = {};
this._router.events.pipe(
filter(evt => evt instanceof NavigationStart || evt instanceof ActivationEnd),
tap(evt => {
if (evt instanceof NavigationStart) pageReloaded.started = true;
else pageReloaded.ended = true;
})
).subscribe(evt => {
if (pageReloaded.started && pageReloaded.ended) console.log('this is a navigation');
else console.log('this is a page reload');
});
}
}
从顶部组件执行此操作很重要,就我而言,我总是从 AppComponent 执行此操作。
注意:这仅检测页面的加载是由导航还是重新加载触发的,它不会干扰这两种情况中的任何一种情况
如果您想要在页面重新加载之前执行某些操作,我建议使用 before unload 事件。我不知道在 Angular 中有任何本地方法可以做到这一点。
我希望有一天这可以帮助别人!
刷新触发Scroll事件对象。
class Scroll { type: EventType.Scroll; routerEvent: NavigationEnd | NavigationSkipped;position: [...];anchor: string | null;toString(): string;}
我使用这个对象来获取NavigationEnd事件:
this.router.events
.pipe(
map((event) => (event instanceof Scroll ? event.routerEvent : event)),
filter((event) => event instanceof ActivationStart || event instanceof NavigationEnd),
takeUntil(this.destroy$)
)