Angular 9、scroll restoration/anchor scrolling 不支持异步数据加载
Angular 9, scroll restoration/anchor scrolling does not work with async data loading
我试图在使用片段通过路由器link 导航后滚动到锚点。
** 组件 1 **
<a routerLink="/training/{{ currentTrainingId }}" fragment="{{currentDomainId}}">
这个 link 应该将用户带到组件 2。我希望通过给元素一个 id 然后使用片段在 URL 中自动添加 #id 来实现锚点滚动。
** 组件 2 **
<div *ngIf="all data has been loaded">
....
<domain-overview *ngFor="let domain of domains" [id]="domain.id"></domain-overview>
</div>
生成的 URL 似乎是正确的。
http://localhost:4200/training/28#40
但是,锚点滚动不会发生。我认为这与异步加载数据有关。执行锚点滚动时域尚未加载..
我创建了一个静态 div,然后锚点滚动就起作用了。
有谁知道如何处理异步数据和锚点滚动吗?
解决方案
不要依赖自动锚点滚动,而是编写自己的滚动功能。基于@Vinaayakh 他的回答,我得到了以下可行的解决方案。
scroll(id){
const elmnt = document.getElementById(id);
elmnt.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
this.route.fragment.subscribe((fragment: string) => {
this.fragment = fragment;
});
稍后,在订阅的完整部分加载所有数据后,我调用了滚动功能。
setTimeout(() => {
this.scroll(this.fragment);
}, 250);
尝试添加此功能
scroll(id){
const elmnt = document.getElementById(id);
elmnt.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
并将函数添加到 HTML
<domain-overview *ngFor="let domain of domains" (click)="scroll(id)" [id]="domain.id"></domain-overview>
更新以包含 ActivatedRoute.snapshot (属性) 您可以在不订阅路由片段的情况下使用:
constructor(private route: ActivatedRoute){
this.fragment = this.route.snapshot.fragment
}
然后在你的 ngOnInit 中:
if(!!this.fragment){
this.scroll(this.fragment)
}
如果需要,您可以将 if 语句放入 setTimeout 中,但这简化了代码,同时不需要在 ngOnDestroy 中取消订阅。
我试图在使用片段通过路由器link 导航后滚动到锚点。
** 组件 1 **
<a routerLink="/training/{{ currentTrainingId }}" fragment="{{currentDomainId}}">
这个 link 应该将用户带到组件 2。我希望通过给元素一个 id 然后使用片段在 URL 中自动添加 #id 来实现锚点滚动。
** 组件 2 **
<div *ngIf="all data has been loaded">
....
<domain-overview *ngFor="let domain of domains" [id]="domain.id"></domain-overview>
</div>
生成的 URL 似乎是正确的。
http://localhost:4200/training/28#40
但是,锚点滚动不会发生。我认为这与异步加载数据有关。执行锚点滚动时域尚未加载..
我创建了一个静态 div,然后锚点滚动就起作用了。
有谁知道如何处理异步数据和锚点滚动吗?
解决方案
不要依赖自动锚点滚动,而是编写自己的滚动功能。基于@Vinaayakh 他的回答,我得到了以下可行的解决方案。
scroll(id){
const elmnt = document.getElementById(id);
elmnt.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
this.route.fragment.subscribe((fragment: string) => {
this.fragment = fragment;
});
稍后,在订阅的完整部分加载所有数据后,我调用了滚动功能。
setTimeout(() => {
this.scroll(this.fragment);
}, 250);
尝试添加此功能
scroll(id){
const elmnt = document.getElementById(id);
elmnt.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
并将函数添加到 HTML
<domain-overview *ngFor="let domain of domains" (click)="scroll(id)" [id]="domain.id"></domain-overview>
更新以包含 ActivatedRoute.snapshot (属性) 您可以在不订阅路由片段的情况下使用:
constructor(private route: ActivatedRoute){
this.fragment = this.route.snapshot.fragment
}
然后在你的 ngOnInit 中:
if(!!this.fragment){
this.scroll(this.fragment)
}
如果需要,您可以将 if 语句放入 setTimeout 中,但这简化了代码,同时不需要在 ngOnDestroy 中取消订阅。