在 Angular 中添加项目时,是否可以移动到特定索引?
Is there a way to move to a specific index when an item is added in the Angular?
我有一些列表,可以 add/remove 列表中的项目。
添加项目时,有没有办法使事件滚动到特定索引(添加项目的位置)?在当前的例子中,项目被添加到列表的前面,所以滚动必须移动到顶部
例如,当我在列表的中间(或底部)时,如果我将项目添加到列表中,滚动条将移动到列表的顶部。 (或移动到某个索引,在本例中,索引 0)。
告诉我如何在不改变示例结构的情况下从父组件滚动到子组件。
你的问题是ViewChild在查询时不会进入更深层次,所以你不能在子元素模板中查询CdkVirtualScrollViewport。我可以通过列表组件中的 自定义更改检测功能解决此问题。
您应该从 app.ts -> addItem() 函数中删除它:
// want to move scroll to the top of the list
this.viewPort.scrollToIndex(0, 'smooth');
并改为在 list 组件 中创建自定义更改检测功能,但首先将 CdkVirtualScrollViewport 的 viewChild 移动到 列表组件:
export class ListComponent {
@ViewChild(CdkVirtualScrollViewport) viewPort: CdkVirtualScrollViewport;
@Input()
data: Favorite[];
@Output()
removeData = new EventEmitter<Favorite>();
remove($event) {
this.removeData.emit($event);
}
ngOnChanges(changes: SimpleChanges) {
if (
changes.data &&
changes.data.currentValue &&
changes.data.previousValue &&
changes.data.currentValue.length >changes.data.previousValue.length
) {
this.viewPort.scrollToIndex(0, 'smooth');
}
}
}
这非常适合我。每次添加项目时,它都会滚动到顶部。
修改后的 stackblitz link:
https://stackblitz.com/edit/angular-ivy-k5pve6?file=src/app/list/list.component.ts
另一个解决方案(也许更好) 可以将 ListComponent 作为模板引用传递给 addItem() 函数,然后使用组件 viewPort 属性 的滚动功能。
列表组件
...
export class ListComponent {
@ViewChild(CdkVirtualScrollViewport)
public viewPort: CdkVirtualScrollViewport;
...
}
带有 ListComponent 模板引用传递的 AppComponentTemplate:
<p>Start editing to see some magic happen :)</p>
<input #inputText />
<button #addButton (click)="addItem(list)">Add New</button>
<list-container #list [data]="favoriteList" (removeData)="remove($event)">
</list-container>
AppComponent->addItem():
addItem(listComp: ListComponent) {
const newItem = {
id: Number(this.input.nativeElement.value) + 1,
title: `item ${Number(this.input.nativeElement.value) + 1}`,
};
this.favoriteList = [newItem, ...this.favoriteList];
listComp.viewPort.scrollToIndex(0, 'smooth');
}
第二个解决方案的 StackBlitz:
https://stackblitz.com/edit/angular-ivy-ofhubv?file=src/app/app.component.html
我有一些列表,可以 add/remove 列表中的项目。 添加项目时,有没有办法使事件滚动到特定索引(添加项目的位置)?在当前的例子中,项目被添加到列表的前面,所以滚动必须移动到顶部
例如,当我在列表的中间(或底部)时,如果我将项目添加到列表中,滚动条将移动到列表的顶部。 (或移动到某个索引,在本例中,索引 0)。
告诉我如何在不改变示例结构的情况下从父组件滚动到子组件。
你的问题是ViewChild在查询时不会进入更深层次,所以你不能在子元素模板中查询CdkVirtualScrollViewport。我可以通过列表组件中的 自定义更改检测功能解决此问题。
您应该从 app.ts -> addItem() 函数中删除它:
// want to move scroll to the top of the list
this.viewPort.scrollToIndex(0, 'smooth');
并改为在 list 组件 中创建自定义更改检测功能,但首先将 CdkVirtualScrollViewport 的 viewChild 移动到 列表组件:
export class ListComponent {
@ViewChild(CdkVirtualScrollViewport) viewPort: CdkVirtualScrollViewport;
@Input()
data: Favorite[];
@Output()
removeData = new EventEmitter<Favorite>();
remove($event) {
this.removeData.emit($event);
}
ngOnChanges(changes: SimpleChanges) {
if (
changes.data &&
changes.data.currentValue &&
changes.data.previousValue &&
changes.data.currentValue.length >changes.data.previousValue.length
) {
this.viewPort.scrollToIndex(0, 'smooth');
}
}
}
这非常适合我。每次添加项目时,它都会滚动到顶部。
修改后的 stackblitz link:
https://stackblitz.com/edit/angular-ivy-k5pve6?file=src/app/list/list.component.ts
另一个解决方案(也许更好) 可以将 ListComponent 作为模板引用传递给 addItem() 函数,然后使用组件 viewPort 属性 的滚动功能。
列表组件
...
export class ListComponent {
@ViewChild(CdkVirtualScrollViewport)
public viewPort: CdkVirtualScrollViewport;
...
}
带有 ListComponent 模板引用传递的 AppComponentTemplate:
<p>Start editing to see some magic happen :)</p>
<input #inputText />
<button #addButton (click)="addItem(list)">Add New</button>
<list-container #list [data]="favoriteList" (removeData)="remove($event)">
</list-container>
AppComponent->addItem():
addItem(listComp: ListComponent) {
const newItem = {
id: Number(this.input.nativeElement.value) + 1,
title: `item ${Number(this.input.nativeElement.value) + 1}`,
};
this.favoriteList = [newItem, ...this.favoriteList];
listComp.viewPort.scrollToIndex(0, 'smooth');
}
第二个解决方案的 StackBlitz:
https://stackblitz.com/edit/angular-ivy-ofhubv?file=src/app/app.component.html