Получение вложенных вложенных коллекций Cloud Firestore при загрузке страницы в Angular - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь создать простое приложение-пример блога на 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 в реальном времени.

Спасибо за помощь!

...