我有一个 Angular 组件,我想在路线更改时使用scrollIntoView。这是我的组件中的相关代码片段:
@ViewChild('structure') structure: ElementRef | undefined;
legacyRoute: string = '';
constructor(private apiService: ApiService, private router: ActivatedRoute, private route: Router, private cdRef: ChangeDetectorRef) { }
ngAfterViewInit() {
this.router.paramMap.subscribe(params => {
this.legacyRoute = params.get('id') || '';
console.log("checking legacy after param map subscription", this.legacyRoute);
setTimeout(() => {
if (this.legacyRoute && this.structure && this.structure.nativeElement) {
console.log("Running scrollIntoView", this.legacyRoute, this.structure, this.structure.nativeElement);
this.structure.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' });
}
}, 1000)
});
}
问题: scrollIntoView 函数在页面刷新时可以正常工作,但在 Angular 路由更改时则无法正常工作。我添加了一个 setTimeout 来延迟该函数,这使得它可以工作,但我知道这不是一个可靠的解决方案。
我尝试过的:
删除 setTimeout 会导致scrollIntoView在路线更改时无法正常工作。
调用scrollIntoView之前确保this.struct.nativeElement有效。
使用 ngAfterViewChecked() 代替 ngAfterViewInit()
预期行为: 我希望在 Angular 应用程序中导航到不同的路线时,scrollIntoView 能够正确执行,而不依赖于 setTimeout。
其他背景:
"dependencies": {
"@angular/animations": "^17.3.0",
"@angular/cdk": "^17.3.9",
"@angular/common": "^17.3.0",
"@angular/compiler": "^17.3.0",
"@angular/core": "^17.3.0",
"@angular/forms": "^17.3.0",
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/platform-server": "^17.3.0",
"@angular/router": "^17.3.0",
"@angular/ssr": "^17.3.7",
"@ngrx/store": "^17.2.0",
"express": "^4.18.2",
"force": "^0.0.3",
"primeicons": "^7.0.0",
"primeng": "^17.17.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
}
我的标题
由于我是 Angular 的新手,我想确保我没有忽略任何重要的事情。您的帮助对我来说意义重大,我真诚地感谢您的时间和帮助。预先感谢您!
也许您可以尝试监听路由器导航结束事件,以确保导航已完成以及信号效果。
这也适用于初始呼叫。我会尝试这样的事情。
private readonly navigationEnd = toSignal(
this.router.events.pipe(filter((event): event is NavigationEnd => event instanceof NavigationEnd))
)
private readonly structure = viewChild('structur')
constructor() {
effect(() => {
// maybe called 2 times if navigation has been ended
// and if structure has been resolved
const navigationEnd = this.navitationEnd();
const structure = this.structure();
// scroll into view
})
}