首页 > 解决方案 > 在 Angular 组件中添加 element.scrollIntoView() 的位置?

问题描述

我有一个显示电影标题列表的 Angular 10 组件,该列表有一个垂直滚动条。其中之一将是当前选定的电影,并以粗体等突出显示。电影列表和选定的电影通过 observables 更新,如下所示:

<div 
    class="overflow-hidden text-nowrap"
    [ngClass]="{'shadow-sm font-weight-bolder': isSelected(film.id)}"
    *ngFor="let film of films" 
    (click)="onClick(film)">
    {{film.title}}
</div>

public ngOnInit(): void {

    this.subs.push(this.filmService.observe().subscribe(films => {
        this.films = films;
        this.changeRef.detectChanges();
    }));

    this.subs.push(this.activeFilmService.observe().subscribe(film => {
        this.activeFilm = film;
        this.changeRef.detectChanges();
    }));
}

public isSelected(id: number): boolean {
    return this.activeFilm && id === this.activeFilm.id;
}

不幸的是,如果用户手动向下滚动以找到它,则通常看不到活动胶片。每次列表或活动影片发生变化时,我都希望看到活动影片。我知道如何使用 @ViewChild 来查找 div 并调用 scrollIntoView() 使其可见。我的问题是我应该在哪里添加此代码?

大概我不能只将scrollIntoView代码添加到订阅的末尾。我假设在尝试更改滚动位置之前,我必须等待 Angular 重新渲染所有元素。我将如何安全地做到这一点?

标签: angularlifecycle

解决方案


您可以执行以下操作。

1)。你不应该在模板中使用函数(isSelected)(以提高性能)

<div 

    #mySelectedFilm                                                         // added template ref variable

    class="overflow-hidden text-nowrap"

    [ngClass]="{'shadow-sm font-weight-bolder': (film.id === activeFilm.id )}"   // using activeFilm.id

    *ngFor="let film of films; let i = index"                                    // let i=index added 

    (click)="onClick(film)"

     id ="{{i}}">                                                                // line added

    {{film.title}}

</div>

2)。确保为可滚动视口/窗口定义固定大小

3)。

 @ViewChildren("mySelectedFilm") ele: QueryList<ElementRef>;


 bringToView(){ 
      for(const ele of this.ele){
         if(ele.nativeElement.id == this.activeFilm.id){
         ele.nativeElement.scrollIntoView(false);
      }
 }

设置activeFilm.id时调用此函数

this.subs.push(this.activeFilmService.observe().subscribe(film => {
        this.activeFilm = film;
        
        this.bringToView(); // you can try putting it after below line also if doesn't work

        this.changeRef.detectChanges();

    }));
}

演示以帮助您了解我到目前为止所解释的内容


推荐阅读