簡體   English   中英

如何在Angular 5中使用rxJS存儲來自API的可觀察數據?

[英]How to store observable data from API with rxJS in Angular 5?

我有一個角度服務,可以從API獲取數據,並且此數據在許多組件中都使用,因此每次調用API來獲取相同的數據都是浪費。

因此,我繼續嘗試使用BehaviorSubjects來存儲數據。 我很好地工作了一點,像這樣使用它:

服務內容

books = new BehaviorSubject<Book[]>(null);
setBooks(book: Book[]) {
    this.books.next(book);
}
getBooks() {
    this.http.get(...).do(
        (res) => {
            this.setBooks(res.books);
        }
    );
}

組件:

ngOnInit() {
    this.booksService.books.subscribe(
        (books) => {
            // in case the api was never called
            if (books == null) {
                return this.booksService.getBooks().subscribe();
            }
            console.log(books);
            // ...
        }
    );
}

有書時,它工作正常,但是如果書是空數組(這是預期的行為之一),則程序將陷入循環,並永遠調用api。 測試它,我發現它被卡在服務調用的.do()部分中,但是我不知道為什么。

在這里讀到BehaviorSubject並不是要使用空初始值,而是像建議的@estus一樣,使用ReplaySubject(1)也會發生同樣的事情。

我想知道是否存在“正確”的方式來存儲數據。 我也不認為使用本地存儲是最好的解決方案,因為它可能會存儲大量數據,並且在應用程序使用過程中會發生很大變化。

這樣做:

服務

// init books as BehaviorSubject with an empty array of type Book
books = new BehaviorSubject<Book[]>([]);

setBooks(book: Book[]) {
     this.books.next(book);
}

 // return books as an Observable
 getBooks(): Observable<Book[]> {
     // only if length of array is 0, load from server
     if (this.books.getValue().length === 0) {
          this.loadBooks();
     }

     // return books for subscription even if the array is yet empty. 
     // It‘ll get filled soon.
     return this.books.asObservable();  
  }  

  private loadBooks(): void {
      this.http.get(...).do(
         (res) => {
             this.books.next(res.books);
       } );
  }

TS-文件

ngOnInit() {
    this.booksService.getBooks().subscribe(
        (books) => {  
            console.log('books: ', books);
        });
}

這里發生的是,您只會加載一次圖書清單。 建立對書籍的訂閱,並且一旦書籍列表到達,新列表就會傳播到所有訂戶。

因此,您應該看到2次控制台日志。 第一個帶有空白列表,第二個帶有書籍。

暫無
暫無

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

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