簡體   English   中英

Angular RxJS Observable(OnInit 和搜索)

[英]Angular RxJS Observable (OnInit and Search)

我仍在使用 Angular 學習 RxJS,我想用正確的方法解決一個基本場景。 我有一個渲染列表的組件,所以當它加載時,在 ngOnInit 事件中,我調用了使用 API 的服務(結果是一個只有 20 個項目的數組,只是為了顯示一些東西,但在數據庫中我可能有 1500 條記錄)。 我目前遇到的問題是:該組件還有一個使用相同 API 的搜索欄,但會發送一個 searchTerm 來過濾基於它的項目。 由於搜索事件僅在用戶在搜索欄中鍵入內容時才會執行,因此如果我刪除 ngOnInit 中的調用,當頁面加載時,我將有一個空屏幕,但是如果我添加該調用,當我搜索事件未執行。 我知道這是因為我在兩個地方都使用了 Exercise$ 屬性,但我不知道如何解決這個問題。 我的問題是,如何為兩個過程使用相同的 Observable? 或者,實現這一目標的最佳方法是什么? 先感謝您。

這是我在組件中的代碼。

組件屬性

exercises$: Observable<ExerciseModel[]>;
searchTerm = new FormControl();
searchTerms$: Observable<string> = this.searchTerm.valueChanges;
exercises$ = this.searchTerms$.pipe(
    tap(() => this.errorMsg = ''),
    debounceTime(1000),
    distinctUntilChanged(),
    switchMap(searchTerm => this._exerciseSrv.getExercisesBySearch({ name: searchTerm })
      .pipe(
        catchError(err => {
          this.errorMsg = err;
          return EMPTY;
        })
      )
    ),
    map((data) => data)
  );

初始化

this.exercises$ = this._exerciseSrv.getExercisesBySearch({name: null}).pipe(
      catchError(errorMessage => {
        this.errorMsg = errorMessage;
        return []
      })
    );

組件 HTML

<div *ngFor="let item of exercises$ | async"></div>

嘗試使用startWith初始化可觀察startWith

exercises$ = this.searchTerms$.pipe(
    startWith(null),
    tap(() => this.errorMsg = ''),
    debounceTime(1000),
    distinctUntilChanged(),
    switchMap(searchTerm => this._exerciseSrv.getExercisesBySearch({ name: searchTerm })
      .pipe(
        catchError(err => {
          this.errorMsg = err;
          return EMPTY;
        })
      )
    ),
    map((data) => data)
  );

並從ngOnInit刪除分配。

您可以在subscribe部分分配您的exercise$值嗎?

組件屬性:

exercises: ExerciseModel[];
searchTerm = new FormControl();
searchTerms$: Observable<string> = this.searchTerm.valueChanges;

ngOnInit:

// get records
this._exerciseSrv.getExercisesBySearch({name: null}).pipe(catchError(errorMessage => {
        this.errorMsg = errorMessage;
        return []
      })). subscribe((data) => this.exercise = data );

// get records base on searchTerms
this.searchTerms$.pipe(tap(() => this.errorMsg = ''),
        debounceTime(1000),
        distinctUntilChanged(),
        switchMap(searchTerm => this._exerciseSrv.getExercisesBySearch({ name: searchTerm })
          .pipe(catchError(err => {
              this.errorMsg = err;
              return EMPTY;
            })
        )
     ), map((data) => data)
).subscribe((data) => this.exercise = data);

組件 HTML:

<div *ngFor="let item of exercises$ | async"></div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM