我是 RxJs 的新手,在我的應用程式中使用 BehaviourSubject 時從 HTTP 請求中獲取回應時遇到問題。這樣做的正確方法是什么?通過使用 chrome 開發工具,我注意到該功能甚至沒有進行網路呼叫。在我嘗試使用 BehaviourSubject 之前,我只使用了一個簡單的 Observable 并且 http 請求有效。我還注意到只是發送一些靜態資料而不是做一個 http 請求然后主題作業。
//Service
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { tap } from 'rxjs/operators';
import { Pokemon } from '../_model/pokemon';
@Injectable({
providedIn: 'root'
})
export class PokemonService {
baseUrl = environment.apiUrl;
private pokemonListSubject = new BehaviorSubject<any>(null);
pokemonList$: Observable<Pokemon> = this.pokemonListSubject.asObservable();
constructor(private http: HttpClient) { }
getPokemonList2(){
//This request works
//this.pokemonListSubject.next('this is a pokemon')
this.http.get<Pokemon>(this.baseUrl `pokemon/ditto`)
.pipe(
tap(value => {
this.pokemonListSubject.next(value)
})
)
}
}
//component
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { Gen } from 'src/app/_model/gen';
import { Pokemon } from 'src/app/_model/pokemon';
import { GensService } from 'src/app/_services/gens.service';
import { PokemonService } from 'src/app/_services/pokemon.service';
@Component({
selector: 'app-screen',
templateUrl: './screen.component.html',
styleUrls: ['./screen.component.css']
})
export class ScreenComponent implements OnInit {
gens$: Observable<Gen[]>;
pokemon2$?: any;
constructor(public pokemonService: PokemonService, private genService: GensService) {
this.gens$ = this.genService.getGens();
this.pokemonService.pokemonList$.subscribe(pokemonList => this.pokemon2$ = pokemonList)
}
ngOnInit(): void {}
getPokemonByGen2(gen: Gen){
this.pokemonService.getPokemonList2();
}
}
//html
<div id="screen">
<div >
<ul>
<li *ngFor="let gen of (gens$ | async)"> <a (click)="getPokemonByGen2(gen)">{{gen.name}}</a></li>
</ul>
</div>
<ng-container *ngIf="pokemon2$" >
{{pokemon2$.name}}
</ng-container>
</div>
uj5u.com熱心網友回復:
使用如下所示的方法,
getPokemonList2(): void {
//This request works
//this.pokemonListSubject.next('this is a pokemon')
this.http.get<Pokemon>(this.baseUrl `pokemon/ditto`)
.subscribe(val => {
this.pokemonList$.next(val);
});
}
uj5u.com熱心網友回復:
您的建構式中不應該有任何邏輯,這就是ngOnInit目的。對于任何邏輯初始化和監聽更改,在這種情況下,您的主題ngOnInit是處理該問題的正確位置。
現在,在您的點擊事件中,您正在呼叫您的服務,但是,沒有人訂閱該 HTTP 呼叫。您只是訂閱了您的主題。
您的代碼中缺少的是:
getPokemonByGen2(gen: Gen){
this.pokemonService.getPokemonList2().subscribe();
}
此外,您訂閱了您自己的特殊 observable,也pokemonList$
很好,但您沒有處理訂閱。您需要存盤該訂閱,以便在您導航到其他地方時可以“銷毀”它,否則,您將在您的應用程式上造成記憶體泄漏。
....
....
mySubscription!: Subscription;
ngOnInit(): void {
this.mySubscription = this.pokemonService.pokemonList$
.subscribe(pokemonList => this.pokemon2$ = pokemonList);
}
ngOnDestroy(): void {
this.mySubscription?.unsubscribe();
}
getPokemonByGen2(gen: Gen){
this.pokemonService.getPokemonList2().subscribe();
}
現在,如果您不想處理訂閱,而不是訂閱您的pokemonList$,您可以通過管道將其存盤在您的本地屬性中,如下所示:
ngOnInit(): void {
this.pokemon2$ = this.pokemonService.pokemonList$
.pipe(
map((pokemonList) => pokemonList)
);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/403698.html
標籤:
下一篇:忽略Angular中的匯入
