【问题标题】:Angular 9 Add new item to list without refreshing listAngular 9将新项目添加到列表而不刷新列表
【发布时间】:2020-09-04 03:34:49
【问题描述】:

我正在开发一个角度应用程序,我可以说我是角度方面的新手。在我的应用程序中,我通过带有可观察数组的 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 获取成功消息后从子组件触发的。

我想问,我的做法对不对?如果不是,那么在列表上执行这种 crud 操作的有效方法是什么?

【问题讨论】:

标签: angular typescript rxjs angular-material


【解决方案1】:

您可以将其添加到您的组件中

   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 键,Angular 将检查每个项目并按 ID 进行差异,而不是刷新整个数组。如果您打开开发人员工具并检查元素,您会注意到只有新添加的项目才会获得 dom 更新。

更新---- 您可以尝试如下更改您的实现,因此您的流引用保持不变,看看是否可以解决问题

dataSet$=new BehaviorSubject([])
ngOnInit(): void {
    this.getGroups().subscribe(group=>dataSet$.next(group));
  } 

refreshGroupList(group){
     this.dataSet$.next(this.dataSet$.value.concat(group))
}

【讨论】:

  • 感谢您的回答,我认为这就是重点;但不幸的是,添加新项目后它仍然是刷新列表。使用异步管道和可观察效果吗?
  • dataSet$ 是我真正的数据源,我将项目添加到此属性,而不是结果集。这个效果如何?
  • dataSet$ 是否有时会返回 falsy 或者它总是产生项目?理论上它不应该受到 *ngIf 的影响,除非它从 false 变为 true 和 true 到 false 等。
  • 我不这么认为它会从 false 变为 true 。在 refreshGroupList 函数中一切正常吗?我基本上只是在当前列表中添加一个新项目。
  • 您的 refreshGroupList 不是一个理想的解决方案,但它仍然不应该导致整个列表刷新。你可以试试行为主体实现
【解决方案2】:

您可以在组件 ChangeDetection: OnPush 上进行设置,并使用 ChangeDetecionRef 服务和方法 markToCheck() 手动告知何时刷新组件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 2013-05-30
    • 2011-10-18
    • 1970-01-01
    相关资源
    最近更新 更多