Субъект поведения не обновляется при изменении Async Angular 10

#angular #rxjs #async-pipe

#angular #rxjs #асинхронный канал

Вопрос:

У меня есть Observable список, который я показываю в своем компоненте. Но когда я обновляю список через свой серверный сервер, список не обновляется async в моем компонентном представлении..

Моя служба (где хранится список):

     export class GameService {
      games: Game[] = []
      public gameSubject = new BehaviorSubject<Game[]>(this.games);
      public readonly games$ = this.gameSubject.asObservable();
    
      constructor(private http: HttpClient) {
        this.getAllGames().subscribe(response => this.gameSubject.next(response))
       }
    
      public createGame(game: Game): Observable<Game> {
        const url = 'http://localhost:8080/api/games';
        return this.http.post<Game>(url, game);
      }
    
      public createAndUpdate(game: Game): void { 
        this.createGame(game).subscribe();
        this.getAllGames().subscribe(response => this.gameSubject.next(response))
    
      }
    
      public getGame(id: number): Observable<Game> {
        const url = 'http://localhost:8080/api/games/sessieId'   id;
        return this.http.get<Game>(url);
      }
    
      public getAllGames(): Observable<Game[]> {
        const url = 'http://localhost:8080/api/games';
        return this.http.get<Game[]>(url);
      }
    
    }
 

component (Где я отображаю список)

      <div fxLayout="column" fxLayoutAlign="center center">
              <ng-template ngFor let-j="index" let-playerA [ngForOf]="gameService.games$ | async">
                <div fxFlex fxLayout="row" *ngIf="j % 3 == 0">
                  <ng-template ngFor let-i="index" let-player [ngForOf]="gameService.games$ | async">
                    <div fxFlex *ngIf="i < j   3 amp;amp; i >= j">
                      <mat-card class="player-card">
                        <mat-card-header>   
                          <mat-card-title>{{ player.user }}</mat-card-title>
                        </mat-card-header>
                        <mat-card-content>
                          <img src="assets/pictures/man.png" />
                        </mat-card-content>
                      </mat-card>
                    </div>
                  </ng-template>
                </div>
              </ng-template>
            </div>
 

Я вызываю этот метод при обновлении списка (создании нового элемента) (метод из сервиса):

     public createAndUpdate(game: Game): void { 
        this.createGame(game).subscribe();
        this.getAllGames().subscribe(response => this.gameSubject.next(response))
    
      }
 

Но мне все равно нужно обновить страницу, чтобы увидеть изменения

Комментарии:

1. Вы можете просто подписаться на gameSubject в шаблоне. Субъект поведения является наблюдаемым. Так что не нужно делать. Как наблюдаемый.

2. Похоже, вы здесь путаете довольно много вещей. Прежде всего, GameService это смесь службы, которая предназначена для подключения к серверной части, и службы для хранения состояния. Я бы рекомендовал этого не делать. Для каждого есть выделенная служба. Один связан с уровнем HTTP, другой связан с уровнем локального состояния. Теперь, второй момент: вы делаете довольно много подписок внутри своего сервиса. Вы действительно не должны этого делать. Попробуйте описать все как наблюдаемые. Subscribe — это то, где реактивное программирование в основном заканчивается. К сожалению, это занимает довольно много времени, чтобы обдумать эту концепцию

Ответ №1:

Вы должны позвонить this.getAllGames() после this.createGame(game) завершения, чтобы получить обновленный список. Поэтому вам придется поместить его внутрь this.createGame(game).subscribe(() => this.getAllGames().subscribe(response => this.gameSubject.next(response))) , но это выглядит слишком уродливо. Правильный способ был бы чем-то вроде

 this.createGame(game).pipe(switchMap(() => this.getAllGames())).subscribe(this.gameSubject)
 

Который отправил бы запрос на создание игры, подождите, пока игра не будет создана на серверной части и ответ не будет отправлен обратно на интерфейс, а затем мы делаем запрос, чтобы получить все игры и отправить их субъекту.