簡體   English   中英

使用Router.navigate()后未調用Observable.subscribe()

[英]Observable.subscribe() not called after using Router.navigate()

我正在創建一個從數據庫中顯示書籍的小應用程序。 我的項目看起來像這樣:

| presentational
| ---> book-card
| ---> book-details
| containers
| ---> book-item
| ---> books
| services
| ---> books

我使用BookItemComponent作為容器,此類與BooksComponent通信。 書籍組件顯示書籍卡片(如引導樣式),書籍卡片組件具有輸入(獲取書籍信息)和輸出(以顯示有關書籍的更多操作和詳細信息)。 以下是這些類的代碼:

book-item.component.ts:

export class BookItemComponent implements OnInit {
  book: Book; /*= {"title": "New harry", "author": "J.K Rowling"};*/

  constructor(private booksService: BooksService, private route: ActivatedRoute) { }

  ngOnInit() {
    console.log("BookItemComponent.ngOnInit()");

    this.booksService.getBooks().subscribe(
      (books) => {
        const param = this.route.snapshot.params.id;
        console.log(param);
        this.book = books.find(book => book.id == param);
      });
  }
}


book-item.component.html:

<p>Book-item</p>
<p *ngIf="!book">No book found..</p>
<app-book-details
    [book]="book" 
    (addToFav)="onAddToFav(book)"></app-book-details>

BookItemComponent類與BooksComponent通信,BooksComponent是主要容器:
books.component.ts

export class BooksComponent implements OnInit {

  books: Book[];

  constructor(private booksService: BooksService, private router: Router) { }

  ngOnInit() {
    this.booksService.getBooks().subscribe(books => {
      this.books = books;
    });
  }

  onShowDetails(event: Book) {
      this.router.navigate(['/', event.id]);
  }
}

最后:
book-card.component.ts:

@Component({
  selector: 'app-book-card',
  templateUrl: './book-card.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styleUrls: ['./book-card.component.css']
})
export class BookCardComponent {
  @Input() book: Book;
  @Output() showDetails = new EventEmitter<Book>();

  showBookDetails(event: Book) {
    if(event) {
      this.showDetails.emit(event);
    }    
  }
}

**問題**:在方法BookItemComponent.ngOnInit()中,當我使用它時:

this.booksService.getBooks().subscribe(
      (books) => {
        const param = this.route.snapshot.params.id;
        this.book = books.find(book => book.id == param);
      });

我可以看到這本書是未定義的,看看這張圖:

在此輸入圖像描述

修訂書未定義:

**問題**:在方法BookItemComponent.ngOnInit()中,當我使用它時:

[在此處插入代碼塊]

我可以看到這本書未定義......

在您的示例中,您不會在OnInit之前定義book。 在渲染模板時(在這種情況下,在您的observable之前並為book設置值),它會拋出錯誤,因為還沒有定義book。

修復此設置的public book: Book = {} as Book; 在TS文件中聲明它的位置。

設置public books: Book[] = [];也不會有害public books: Book[] = [];

修復加載錯誤:

這花了我很長時間,作為免責聲明,我不是AngularFire的專家,但是在你的books.service.ts中,你在構造函數中定義了books $。 然而,這只被稱為一次。 為了讓我能夠加載你的書籍,我必須重新定義書籍$變量。 為了方便起見,我添加了一個私有函數,您可以在需要時重用它。 以下是獲取書籍和輔助函數的樣子:

  getBooks(): Observable<Book[]> {
    this.setBooks();
    console.log('BooksService.getBooks() called');
    return this.books$.pipe(catchError((error: any) => Observable.throw(error.json())));
  }

  private setBooks(): void {
    this.books$ = this.booksCollection.snapshotChanges().pipe(
      map(actions => actions.map(action => {
        const data = action.payload.doc.data() as Book;
        const id = action.payload.doc.id;
        return { id, ...data };
      }))
    );
  }

暫無
暫無

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

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