Я пытаюсь создать простое приложение-пример блога на Angular с помощью Google Cloud Firestore.
Данные в Firestore структурированы следующим образом:
posts
post1
name: "Post about stuff"
content: "This is a post about stuff."
comments
comment1
title: "First"
content: "I was the first to comment."
Я пытаюсь:
- извлечение сообщения и его комментариев при загрузке страницы
- отображение сообщения и его комментариев
- позволяет пользователям обновлять сообщение и добавлять комментарии к сообщению
Проблема, с которой я сталкиваюсь, состоит в том, что комментарии недоступны, пока сообщение не будет возвращено из Firebase.Моим решением этой проблемы является сопоставление вызова getPost с getComments, чтобы после получения сообщения выполнялся вызов getComments:
post.service.ts
export class PostService {
postSelected$: Observable<Post>;
// Keep comment collection around to easily get and add comments
commentCollection$: Observable<AngularFirestoreCollection<Comment>>;
postId = "0";
constructor(private angularFirestore: AngularFirestore, private userService: UserService) {
this.postSelected$ = this.getPost(userService.getUserId(), this.postId);
this.commentCollection$ = this.postSelected$.pipe(map(post => {
return this.getCommentCollection(userService.getUserId(), post.id);
}));
}
getPost(userId: string, id: string): Observable<Post> {
return this.angularFirestore.doc(`users/${userId}/posts/${id}`).valueChanges().pipe(map((firebasePost: any) => {
return { id, ...firebasePost };
}));
}
updatePost(postUpdate: {name?: string, content?: string}): void {
/* update post */
}
getCommentCollection(userId: string, postId: string): AngularFirestoreCollection<Comment> {
return this.angularFirestore.collection(`users/${userId}/posts/${postId}/comments`, ref => ref.orderBy("displayOrder", "asc"));
}
getComments(userId: string, postId: string): Observable<any> {
const commentCollection = this.getCommentCollection(userId, postId);
return this.getDocuments(commentCollection);
}
getDocuments(collection: AngularFirestoreCollection<any>): Observable<any> {
return collection.snapshotChanges().pipe(map(snapshotChanges => {
return snapshotChanges.map(snap => {
const data = snap.payload.doc.data();
const id = snap.payload.doc.id;
return { id, ...data };
});
}));
}
addComment(comment: { title: string; content: string }): void {
this.commentCollection$.pipe(map(commentCollection => {
commentCollection.add(comment as any);
}));
}
}
post.component.ts
export class PostComponent implements OnInit {
post$: Observable<Post>;
commentCollection$: AngularFirestoreCollection<Comment>;
comment$: Observable<Comment>;
postNameControl: FormControl;
postContentControl: FormControl;
constructor(private userService: UserService, private postService: PostService) {
}
ngOnInit() {
this.postNameControl = new FormControl();
this.postContentControl = new FormControl();
this.post$ = this.postService.postSelected$;
this.post$.subscribe((post: any) => {
const { name, content } = post;
this.postNameControl.setValue(name);
this.postContentControl.setValue(content);
});
this.postNameControl.valueChanges.subscribe(name=> {
this.postService.updatePost({ name });
});
this.postContentControl.valueChanges.subscribe(content => {
this.postService.updatePost({ content });
});
}
}
Комментарии будут иметь те же функции, что и сообщения.
Проблема в том, что функция addComment не работает.У меня такой вопрос:
- Есть ли лучший способ отобразить коллекцию и ее вложенную коллекцию при загрузке страницы?
- Если нет, то почему эта, казалось бы, простая функция addComment не работает?
Я немного осмотрелся и не видел ни документации, ни руководств по передовым методам загрузки коллекции и ее подколлекции при загрузке страницы.Большинство ресурсов AngularFire2 в Интернете охватывают только основные операции CRUD, а другие материалы обычно устарели или используют базу данных Firebase в реальном времени.
Спасибо за помощь!