#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)
Который отправил бы запрос на создание игры, подождите, пока игра не будет создана на серверной части и ответ не будет отправлен обратно на интерфейс, а затем мы делаем запрос, чтобы получить все игры и отправить их субъекту.