问题描述
我有一个包含多个元素的 Angular Material 列表,其中可以选择其中之一.
I have an Angular Material list with multiple elements, where one of them can be selected.
当我加载此列表时,我想将列表向上滚动到所选元素,以使其更加可见.有什么办法吗?
When I load this list I want to scroll list up to that selected element, to make it more visible. Is there any option?
我正在考虑使用 ngOnInit 之类的东西来检查是否选择了项目,但我真的不知道如何将此列表滚动到该项目.
I was thinking about something like in ngOnInit to check if item is selected, but I have really no idea how to scroll this list up to that item.
注意:不应该滚动整个页面,只应该滚动列表中的元素.
Note: not whole page should be scrolled, only the elements on the list.
component.html
component.html
<mat-nav-list>
<mat-list-item *ngFor="let item of items" (click)="itemClick(item)"
[ngClass]="item.selectedClass">
{{item.someValue}}
</mat-list-item>
</mat-nav-list>
component.ts
component.ts
private itemClick(item: Item): Observable<any> {
if (item) {
this.something = item;
this.items.forEach(item => {
if (item && item.name === item.name) {
item["selectedClass"] = "item-selected";
} else {
item["selectedClass"] = undefined;
}
});
} else {
this.something = null;
this.items.forEach(item => {
item["selectedClass"] = undefined;
});
}
return of(null);
}
推荐答案
查看此演示:https://stackblitz.com/edit/angular-yjbpoq?file=src%2Fapp%2Fhello.component.ts
要点是将新指令附加到列表和每个列表项:
The gist is that you attach a new directive to your list and to each of your list items:
<mat-list appScrollable ...>
<mat-list-item appOffsetTop ...>
...
</mat-list-item>
</mat-list>
列表中的可以为列表设置scrollTop
(或使用scrollTo
,或其他):
The one on the list can set the scrollTop
(or use scrollTo
, or whatever) for the list:
@Directive({selector: '[appScrollable]'})
export class ScrollableDirective {
constructor(private _el: ElementRef) {}
set scrollTop(value: number) { this._el.nativeElement.scrollTop = value; }
}
并且列表项上的可以报告它们的offsetTop
s:
And the one on the list items can report their offsetTop
s:
@Directive({ selector: '[appOffsetTop]'})
export class OffsetTopDirective {
constructor(private _el: ElementRef) { }
get offsetTop(): number { return this._el.nativeElement.offsetTop; }
}
在组件中通过@ViewChild
和@ViewChildren
访问每种类型的指令:
Each type of directive is accessed in the component via @ViewChild
and @ViewChildren
:
@ViewChildren(OffsetTopDirective) listItems: QueryList<OffsetTopDirective>;
@ViewChild(ScrollableDirective) list: ScrollableDirective;
在 AfterViewInit
生命周期钩子中,会在项目列表中搜索与当前所选项目匹配的项目(此处随机设置以进行说明).然后将列表的 scrollTop
设置为该项目的 offsetTop
:
In the AfterViewInit
life cycle hook, the list of items is searched for the one that matches the current selected item (set randomly here for illustration purposes). The list's scrollTop
is then set to that item's offsetTop
:
// Inside your component
selectedItem = Math.floor(Math.random() * 500);
items = new Array(500).fill(0).map((_, i) => `Item ${i}`);
ngAfterViewInit() {
this.list.scrollTop = this.listItems.find((_, i) => i === this.selectedItem).offsetTop;
}
这篇关于Material Angular 滚动到 mat-list 上的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!