英文:
angular RouteReuseStrategy scroll position keep
问题
角度 RouteReuseStrategy 滚动位置错误。
当我从另一个页面返回到列表页面时,滚动条回到了顶部。
英文:
angular RouteReuseStrategy scroll position error.
When I returned to the list page from another page, the scroll bar went back to the top
import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router';
export class SystemRouteReuseStrategy implements RouteReuseStrategy {
handlers: {[key: string]: DetachedRouteHandle} = {};
shouldDetach(route: ActivatedRouteSnapshot): boolean {
if (route.data.reuse) {
return true;
}
return false;
}
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
this.handlers[route.routeConfig.path] = handle;
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
return this.handlers[route.routeConfig.path];
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig;
}
}
答案1
得分: 2
如果您不是使用窗口滚动,而是使用具有自动溢出的 div,请订阅路由事件并保存位置。
以下是一个示例(我正在使用 Angular Material Sidenav 作为容器,但您可以更改为普通的 div)
lastPosition: number
lastRoute: string
@ViewChild('grid') grid: MatDrawerContent // 更改为 ElementRef 或其他类型
constructor(private router: Router) {}
ngOnInit() {
this.router.events.pipe(
filter((events) => events instanceof NavigationStart || events instanceof NavigationEnd)
).subscribe(event => {
if (event instanceof NavigationStart && event.url !== this.lastRoute) {
this.lastRoute = this.router.url
this.lastPosition = this.grid.measureScrollOffset('top') // 获取 scrollTop 属性
// this.lastPosition = this.grid.nativeElement.scrollTop
}
else if (event instanceof NavigationEnd && event.url === this.lastRoute) {
this.grid.scrollTo({ top: this.lastPosition }) // 将 scrollTop 设置为上次位置
// this.grid.nativeElement.firstChild.scrollTop = this.lastPosition
}
})
}
英文:
If you are not using the window scrolling but a div with auto overflow, you should subscribe to the router events and save the position.
Here is an example (I'm using Angular Material Sidenav as a container, but you can change to a general div)
<!-- language: typescript -->
lastPosition: number
lastRoute: string
@ViewChild('grid') grid: MatDrawerContent // change to ElementRef or other type
constructor(private router: Router) {}
ngOnInit() {
this.router.events.pipe(
filter((events) => events instanceof NavigationStart || events instanceof NavigationEnd)
).subscribe(event => {
if (event instanceof NavigationStart && event.url !== this.lastRoute) {
this.lastRoute = this.router.url
this.lastPosition = this.grid.measureScrollOffset('top') // get the scrollTop property
// this.lastPosition = this.grid.nativeElement.scrollTop
}
else if (event instanceof NavigationEnd && event.url === this.lastRoute) {
this.grid.scrollTo({ top: this.lastPosition }) // set scrollTop to last position
// this.grid.nativeElement.firstChild.scrollTop = this.lastPosition
}
})
}
答案2
得分: 0
我指的是ionic,
添加了一个新的<router-outlet>
,名为<active-outlet>
。
它不会销毁组件,组件将被设置为隐藏。
并添加一个新的生命周期函数
ngOnChanges
ngOnInit <- 第一次进入创建组件
onReuse <- 第二次进入或路由返回重用组件
ngDoCheck
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
onLeave <- 路由级别
ngOnDestroy <- 手动销毁触发
英文:
I refer to ionic,
A new <router-outlet>
named <active-outlet>
is added.
It will not destroy the component, The component will be set to hidden.
And add a new life cycle function
ngOnChanges
ngOnInit <- first entry create component
onReuse <- second entry or router back reuse component
ngDoCheck
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
onLeave <- router level
ngOnDestroy <- Manual destroy trigger
答案3
得分: -1
非常感谢。我已经重新构建了路由出口以解决这个问题,但会占用大量内存。建议参考 Ionic 和 ion-router。
英文:
Thank you very much. I have rebuilt the router-outlet to solve this problem, but it will take up a lot of memory. Recommended reference ionic, ion-router
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论