Изменение наблюдаемой коллекции и использование асинхронного канала не обновляет DOM? - PullRequest
1 голос
/ 09 июня 2019

Я использую асинхронный канал для подписки на коллекцию элементов в массиве. Мой шаблон выглядит следующим образом:

`

<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()));
  }

`

В пользовательском интерфейсе я отображаю кнопку удаления для каждого отображаемого элемента снаряжения. Когда пользователь нажимает на эту кнопку удаления, я хотел бы изменить наблюдаемую коллекцию gearItems $ в сервисе, чтобы пользовательский интерфейс обновлялся и отражал обновленную коллекцию. Вот мой код в моем файле 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 действительно выполняется, но в пользовательском интерфейсе ничего не обновляется. Я понятия не имею, почему это так. Это потому, что я не следую никаким ценностям? Я думал, что метод deleteGearItem(Id: number) возвращает обновленную коллекцию gearItem, которая должна вызывать обнаружение изменений?

1 Ответ

1 голос
/ 09 июня 2019

= сделал копию ссылки, как вы можете видеть здесь:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...