使用 Router.navigate() 后未调用 Observable.subscribe()
Observable.subscribe() not called after using Router.navigate()
我正在创建一个显示数据库中书籍的小应用程序。
我的项目如下所示:
| presentational
| ---> book-card
| ---> book-details
| containers
| ---> book-item
| ---> books
| services
| ---> books
我使用 BookItemComponent 作为容器,这个 class 与 BooksComponent 通信。
Books 组件显示书籍卡片(如 bootstrap 样式),books-card 组件具有输入(获取书籍信息)和输出(以显示有关书籍的更多操作和详细信息)。
这是这些 classes 的代码:
本书-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);
});
}
}
本书-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>
class BookItemComponent 与作为主要容器的 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]);
}
}
最后:
本书-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);
});
我可以看到那本书是未定义的,看这张图:
修复书未定义:
** PROBLEM ** : In the method BookItemComponent.ngOnInit(), when I use this :
[insert code block here]
I can see that book is undefined...
在您的示例中,直到 OnInit 才定义 book。呈现模板时(在本例中,在您的可观察对象之前并为书设置值)它会抛出错误,因为书尚未定义。
修复此集合 public book: Book = {} as Book;
在 TS 文件中声明它的位置。
设置public books: Book[] = [];
也没什么坏处
修复加载错误:
这花了我很多时间,作为免责声明,我不是 AngularFire 的专家,但在您的 books.service.ts 中,您在构造函数中定义了 books$。然而,这只被调用了一次。为了让我加载您的书籍,我必须重新定义 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 };
}))
);
}
我正在创建一个显示数据库中书籍的小应用程序。 我的项目如下所示:
| presentational
| ---> book-card
| ---> book-details
| containers
| ---> book-item
| ---> books
| services
| ---> books
我使用 BookItemComponent 作为容器,这个 class 与 BooksComponent 通信。
Books 组件显示书籍卡片(如 bootstrap 样式),books-card 组件具有输入(获取书籍信息)和输出(以显示有关书籍的更多操作和详细信息)。
这是这些 classes 的代码:
本书-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);
});
}
}
本书-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>
class BookItemComponent 与作为主要容器的 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]);
}
}
最后:
本书-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);
});
我可以看到那本书是未定义的,看这张图:
修复书未定义:
** PROBLEM ** : In the method BookItemComponent.ngOnInit(), when I use this :
[insert code block here]
I can see that book is undefined...
在您的示例中,直到 OnInit 才定义 book。呈现模板时(在本例中,在您的可观察对象之前并为书设置值)它会抛出错误,因为书尚未定义。
修复此集合 public book: Book = {} as Book;
在 TS 文件中声明它的位置。
设置public books: Book[] = [];
修复加载错误:
这花了我很多时间,作为免责声明,我不是 AngularFire 的专家,但在您的 books.service.ts 中,您在构造函数中定义了 books$。然而,这只被调用了一次。为了让我加载您的书籍,我必须重新定义 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 };
}))
);
}