我正在开发一个角度应用程序,可以说我在角度上是新手。在我的应用程序中,我将通过带有可观察数组的httpclient从服务器绑定数据到基本列表,如下所示。然后,我添加了一个新项目以列出其他组件。列表组件和添加新项组件都在同一页面上。
绑定数据并添加新数据没有问题。添加新商品后出现问题。将新项目添加到列表的数据源后,整个组件将刷新;但是我不想要这个,我想添加新元素而不刷新列表。
简化代码在这里。 我的包含列表的组件:
export class GroupSetupComponent implements OnInit {
dataSet$: Observable<Group[]>;
constructor (private groupService : GroupService) {}
ngOnInit(): void {
this.getGroups();
}
getGroups() {
this.dataSet$ = this.groupService.getGroups();
}
refreshGroupList(group: Group) {
if(group) {
// I have tried getting all list from database again
// this.getGroups();
// than I tried to add new item to existing observable array
this.dataSet$ = this.dataSet$.
pipe(
map(data =>
{
data.push(group);
return dataSet;
}));
}
}
}
和组件模板:
<div *ngIf="dataSet$ | async as resultSet;">
<mat-card>
<mat-card-content>
<mat-selection-list>
<mat-list-option *ngFor="let item of resultSet;" [value]="item.id" [disableRipple]="true">
{{item.name}}
</mat-list-option>
</mat-selection-list>
</mat-card-content>
</mat-card></div>
refreshGroupList 函数是在将新项添加到数据库并从api获取成功消息之后从子组件触发的。
我想问一下,我做的方式正确与否?如果不是,在列表上执行这种分类操作的有效方法是什么?
答案 0 :(得分:2)
您可以将其添加到您的组件中
byId(index, item) {
return item.id;
}
并修改ngFor
<mat-list-option *ngFor="let item of resultSet; trackBy: byId" [value]="item.id" [disableRipple]="true">
{{item.name}}
</mat-list-option>
通过提供trackBy键,角度将检查每个项目并按ID进行比较,而不是刷新整个数组。如果您打开开发人员工具并检查元素,您会注意到只有新添加的项目才能获得dom更新。
更新---- 您可以尝试如下更改实现,以便流参考保持不变,看看是否可以解决问题
dataSet$=new BehaviorSubject([])
ngOnInit(): void {
this.getGroups().subscribe(group=>dataSet$.next(group));
}
refreshGroupList(group){
this.dataSet$.next(this.dataSet$.value.concat(group))
}
答案 1 :(得分:0)
您可以在组件go []
上进行设置,并使用ChangeDetecionRef服务和方法ChangeDetection: OnPush
手动告知何时应刷新组件。