【问题标题】:Firestore Angular Collection inside Document文档内的 Firestore Angular 集合
【发布时间】:2020-08-18 22:37:52
【问题描述】:

我为每位讲师收集了一组文档,并且我希望为每个文档收集另一个 cmets。我找不到阅读该子集的方法。这是结构:

我从这里的服务中获取特定的 ID:

getInstructor(iid: string) {
    this.instructorDoc = this.afs.doc<Instructors>(`instructors/${iid}`);
    return this.instructorDoc.valueChanges();  
}

我在导师页面调用函数:

getInstructor(): void {
    const iid = this.route.snapshot.paramMap.get('iid');
    this.instructorsService.getInstructor(iid).subscribe(instructor => this.instructor = instructor);   
}

我还有一个教师界面:

export interface Instructors {
  iid: string;
  first_name: string;
  last_name: string;
  category: string;
  location: string;
  description: string;
  photoURL: string;
}

最后我得到了这样的讲师组件的 html:

<div *ngIf="instructor" class="card" style="width: 18rem;">
  <img [src]="instructor.photoURL || '//:0'" alt="" class="card-img-top">
  <div class="card-body">
    <h5 class="card-title">{{ instructor.iid }} {{ instructor.first_name }} {{ instructor.last_name }}</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's
      content.</p>
  </div>
</div>

所有代码都有效。我只是被卡住了,不知道如何从这里走。我应该在讲师界面中以某种方式声明 cmets 吗?还应该以某种方式获取评论的 id(可能在评论文档中添加 cid 字段)。以及我将如何在 html 中显示评论内容。我是 JavaScript/TypeScript/Angular 的新手,也许这些事情很简单,但我无法在 google 上找到有关特定情况的有用信息。

【问题讨论】:

    标签: javascript angular typescript firebase google-cloud-firestore


    【解决方案1】:

    您应该能够执行以下操作以检索评论文档:

    getComment(iid: string, commentId: string) {
        this.commentDoc = this.afs.doc<Comment>(
            `instructors/${iid}/comments/${commentId}`
        );
        return this.commentDoc.valueChanges();  
    }
    

    用这个接口或类似的:

    export interface Comment {
        id?: string;
        content: string;
    }
    

    关于获取评论ID,我认为这真的取决于你在做什么。例如,如果您要发布包含多个人的多个 cmets 的帖子,如果可以与评论进行交互,那么将评论 ID 留在 HTML 标记内是一个好主意,以便可以检索它以执行查询。在另一种情况下,您可能希望迭代所有 cmets,这会有所不同。

    您问题的最后一个方面可能需要进一步澄清,并且可能值得提出另一个问题来更详细地了解您的应用程序。


    在讨论了 cmets 中的问题后,我发现对应用程序的工作流程缺乏了解。我将尝试解释缺少的内容,并展示如何修复它。

    误解

    设计的网络具有在src/app/app-routing.module.ts 中定义的路由。定义了这些路由:

    {
        path: '',
        redirectTo: '/instructors',
        pathMatch: 'full'
    },
    {
        path: 'instructors',
        component: InstructorsComponent
    },
    {
        path: 'instructors/:iid',
        component: InstructorDetailsComponent,
    }
    

    我们可以从那里了解到/instructors 将作为索引页面,/instructors/:iid 将是每个讲师的详细信息。

    当用户访问您的主页并单击讲师的个人资料时,请注意您访问/instructors/:iid 的方式。因此,您转发讲师的 ID (iid)。这是正确的,因为我们不需要在 URL 上转发它,我们只是在检查讲师。

    const cid = this.route.snapshot.paramMap.get('cid');
    

    因此,instructor-details.component.ts 文件中的上述行没有意义,因为它检索了参数cid,它没有被转发到教师详细信息的 URL 上。

    实际上,如果将该行更改为const cid = "a8OA7dCBNuNE8uTwgvhk",您将看到整个功能正常工作,并且可以正确显示在第一位讲师 (5EdG4liyxxjam9BrCt0T) 的页面上。

    修复

    据我了解,您希望在其详细信息页面上显示讲师的所有 cmets。这意味着应用程序必须检索相应讲师的子集合comments 并显示它们。

    为了解决这个问题,我修改了三个文件:

    instructor-details.component.ts

    首先必须删除参数cid 的检索,因为它永远不会存在。以下设置告诉我们,函数InstructorsService.getComments 将检索讲师iid 的所有cmets 并将它们返回以显示它们。

    getComments(): void {
        const iid = this.route.snapshot.paramMap.get('iid');
        this.instructorsService.getComments(iid).subscribe(comments => {
            this.comments = comments;
        });
    }
    

    instructors.service.ts

    现在这个函数必须检索整个 cmets 集合,而不是一个具有 id 的集合。请注意,commentDoc 现在已更改为 commentCol 并更改了其类型,因为查询现在检索的是整个集合而不是单个文档。

    import {AngularFirestore, AngularFirestoreDocument, AngularFirestoreCollection} from '@angular/fire/firestore';
    
    [..]
    
    export class InstructorsService {
        instructorDoc: AngularFirestoreDocument<Instructors>;
        commentCol: AngularFirestoreCollection<Comments>;
    
        [..]
    
        getComments(iid: string) {
            this.commentCol = this.afs.collection<Comments>(`instructors/${iid}/comments`);
            return this.commentCol.valueChanges();
        }
    
    }
    

    instructor-details.component.html

    在 HTML 组件中,它不再显示值,而是更改为迭代器 ngFor,因为该组件现在正在接收 列表 文档。

    <div *ngFor="let comment of comments"> {{comment.content}} </div>
    

    【讨论】:

    • 我希望每个用户都能在每个讲师页面上发表评论,所以我想要来自多个 ppl 的多个 cmets。我将您的建议添加到 html 中:
      {{cmets.content}}
      但内容没有出现。
    • 检索返回什么?在其中记录内容以了解检索信息或显示信息是否有问题。
    • 该代码的问题在于cidInstructorDetailsComponent.getComments 检索时是undefined。如果我将 cid 硬编码为 a8OA7dCBNuNE8uTwgvhk,我可以在 James Smith 的个人资料中看到内容“123asd”。
    • 但它是如何未定义的?我的意思是为什么instructor.first_name 不是未定义的?我在接口上以相同的方式声明它们。我错过了什么吗?再次抱歉,如果这很愚蠢,但我对所有这些都没有太多经验。
    • 你帮了我很多。我现在看到了我缺少的东西,即检索子集合的方式。非常感谢!
    猜你喜欢
    • 2018-05-11
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 2022-01-07
    • 2018-10-21
    • 2018-04-09
    • 1970-01-01
    相关资源
    最近更新 更多