修改可观察的集合并使用异步管道,是否不会更新DOM?

时间:2019-06-08 21:30:34

标签: angular rxjs

我正在使用异步管道来订阅数组中的项目集合。我的模板如下所示:

`

<ng-container *ngIf="gearItems$ | async as gearItems">
        <ng-container *ngFor="let gearItem of gearItems">
          <app-merchandise-item
            [admin]="isAdmin"
            class="list-item"
            [gearItem]="gearItem"
          >
          </app-merchandise-item>
        </ng-container>
      </ng-container>

I then have the following in my component to capture the stream coming from the service:

gearItems$ = this.merchandiseService.gearItems$;

`

通过以下实现,我通过解析获得了gearItems$集合:

MerchandiseService.ts

`

resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Promise<any> | any {
    console.log("Inside of the resolver");
    return (this.gearItems$ = this.http
      .get<GearItem[]>(this.merchandiseUrl)
      .pipe(shareReplay()));
  }

`

在ui中,我为显示的每个装备显示一个删除按钮。当用户单击该删除按钮时,我想做的就是修改服务中的可观察集合gearItems $并更新UI并反映更新后的集合。这是我在MerchandiseService.ts文件中执行过滤的代码。

`

deleteGearItem(Id: number): Observable<GearItem[]> {
    // remove gear item
    return (this.gearItems$ = combineLatest([
      this.gearItems$,
      this.http.delete<void>(`${this.merchandiseUrl}/${Id}`, this.headers)
    ]).pipe(
      map(([gearItems, deleted]: [GearItem[], void]) => {
        console.log("Inside delete");
        gearItems = gearItems.filter(gearItem => gearItem.id !== Id);
        return gearItems;
      }),
      catchError(this.handleError)
    ));

`

delete方法中的代码实际上确实可以执行,但是UI中没有任何更新。我不知道为什么会这样。是因为我不重视任何价值吗?我以为deleteGearItem(Id: number)方法返回更新的gearItem集合,应该触发更改检测?

1 个答案:

答案 0 :(得分:1)

=复制了一份参考文献,就像您在这里看到的一样:

var bob1 = {test: 'test1'} // bob1.test = 'test1'
var bob2 = bob1; // bob2.test = 'test1'
var bob1 = {test: 'test2'}
// bob1.test = 'test2'
// bob2.test = 'test1'

所以我认为最好始终保持相同的引用。

一种方法是使用BehaviorSubject并在添加或删除后在其中发射新值。

您可以将其作为mySubject.asObservable()从服务中导出。

您的代码必须是什么样子

private gearItems = new BehaviorSubject<GearItem[]>([]);
gearItems$ = gearItems.asObservable();

resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): void {
    this.gearItems$ = this.http
      .get<GearItem[]>(this.merchandiseUrl)
      .pipe(tap(response => this.gearItems.next(response));
}


deleteGearItem(Id: number): void {
    const newGearItems = this.gearItems.getValue().filter(gearItem => gearItem.id !== Id);
    this.gearItems.next(newGearItems);
}