typescript - Angular - HTTP isteğini yeniden yükle


Angular 5 kullanıyorum ve aşağıdaki sorunla karşılaştım:

Yıl parametresi içeren bir rotam var. İlgili bileşen şimdi o yıl için verileri göstermeli, bu veriler bir servis tarafından getirilir. Böyle bir URL'ye ilk kez yönlendirildiğinde, bu düzgün çalışır. Eğer yıl parametresini değiştirirsem, bileşen yeniden yüklenmez (beklendiği gibi), sadece OnInit() yeniden çağrılır. Bu yöntemde, servisi yeni yıl ile çağırarak verileri yeniden yüklemeye çalışıyorum, ama işe yaramıyor. İşte kodum:

test.component.ts:

public ngOnInit() {
    this.route.paramMap.subscribe( params => {
        if (params.has('year')) {
            this.loadData(params.get('year'));
        } else {
            this.loadData();
        }
    });
}

public loadData(year?: string): void {
    this.testService.getData(year).subscribe(data => {
        // edit and set to variables
    });
}

test.service.ts:

public getData(year) {
    return Observable.forkJoin(
        this.getPart1(year),
        this.getPart2(year)
    );
}

private getPart1(year): Observable<CustomObject[]> {
    let url = this.baseUrl;
    if (year) url = url.concat("?year=" + year);
    return this.http.get<CustomObject[]>(url, httpOptions).pipe(
        catchError(this.handleError<CustomObject[]>())
    )
}

private getPart2(year): Observable<OtherCustomObject[]> {
    let url = this.baseUrl + '/path';
    if (year) url = url.concat("?year=" + year);
    return this.http.get<OtherCustomObject[]>(url, httpOptions).pipe(
        catchError(this.handleError<OtherCustomObject[]>())
    )
}

Observable'ı HTTP isteğini yeniden yüklemeye nasıl zorlayabilirim? Observables yerine bir (Replay)Subject kullanmayı denedim, ama bu işe yaramadı.

Her türlü yardım çok takdir edilir :)

Cevap #1

Bunun için switchMap ile bir BehaviorSubject kullanabilirsiniz:

//First of all, create your reloader subject
reloader$ = new BehaviorSubject(null);

//Then connect it to your observable
public getData(year) {
    return this.reloader$.switchMap(() => Observable.forkJoin(
        this.getPart1(year),
        this.getPart2(year)
    ));
}

Çünkü bu bir BehaviorSubject, ilk çağrı mükemmel bir şekilde çalışacaktır çünkü ilk değer olarak null verecektir.

Sonra, temel bir reload() metodu oluşturabilirsiniz:

public reload(){
  this.reloader$.next(null);
}

Çünkü bu, reloader$'ın gözlemlenebilir bir şekilde yeni bir değer yaymasını sağlayacak, gözlemlenebilir zincirin geri kalanı tekrar tetiklenecek ve verilerinizi yeniden yüklemek için yeni istekler yapılacaktır.

İlgili makaleler