在Angular中加载页面后检索嵌套的Cloud Firestore子集合

时间:2018-09-27 19:36:02

标签: angular firebase rxjs google-cloud-firestore angularfire2

我正在尝试使用Google Cloud Firestore在Angular中创建一个简单的博客示例应用程序。

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的实时数据库。

感谢您的帮助!

0 个答案:

没有答案