如何使用 AngularFire 创建(设置)数据到 Firestore?

How to create (set) data to Firestore using AngularFire?

我正在关注 AngularFire Quickstart tutorial。我开始使用 Read,它在 Angular 视图中显示我的 Firestore 数据库中的数据。我不知道如何让 Create (set) 工作。

我的 app.component.html 显示一个带有 Submit 按钮的小文本表单字段,并显示 Firestore 数据库中的值:

<form (ngSubmit)="onSubmit()">
  <input type="text" [(ngModel)]="name" name="name">
  <button type="submit" value="Submit" >Submit</button>
</form>

<ul>
  <li class="text" *ngFor="let item of items | async">
    {{item.name}}
  </li>
</ul>

我的 app.component.ts 文件有一个函数 onSubmit(),它在用户单击 Submit 按钮时执行。它记录用户在文本表单字段中输入的名称。下一行抛出这个错误:

TS2339: Property 'firestore' does not exist on type 'AppComponent'.

23     this.firestore.collection('items').doc('item').set({name: this.name}); // error is here

这是我的 app.component.ts:

import { Component } from '@angular/core';
import { AngularFirestore } from '@angular/fire/compat/firestore';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  items: Observable<any[]>;
  constructor(firestore: AngularFirestore) {
    this.items = firestore.collection('items').valueChanges();
  }

  name: string | null = null;

  onSubmit() {
    console.log(this.name);
    this.firestore.collection('items').doc('item').set({name: this.name}); // error is here
    return // return what?
  }
}

这与 Tour of Heroes 教程的模式相同:

export class HeroService {

  constructor(private logger: Logger) {  }

  getHeroes() {
    this.logger.log('Getting heroes ...');
    return HEROES;
  }
}

我的app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';

// Firebase
import { AngularFireModule } from '@angular/fire/compat';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFirestoreModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

观点:

还有我的 Firestore 数据库:

我认为这里的问题与 TypeScript 有关。我相信 best-practice,在这种情况下,您可以在 firestore: Firestore 前面使用 private 访问修饰符,同时将其注入到您正在使用它的组件或服务的构造函数中,在你的情况下 app.component.ts.

private 访问修饰符做了几件事:

  1. 它使 属性 成为 class 的成员(类似于您在 class firestore: any; 中声明 属性)
  2. 它使 属性 'private',仅在 class 中可用但在模板中不可用(在开发期间 - 在生产中不强制执行).

constructor(private firestore: AngularFirestore) {
  this.items = firestore.collection('items').valueChanges();
}

史蒂夫的答案有效,但我不明白为什么有效。玩玩,这三个都有效:

constructor(private firestore: AngularFirestore) {
constructor(protected firestore: AngularFirestore) {
constructor(public firestore: AngularFirestore) {

这行不通:

constructor(firestore: AngularFirestore) {

根据 TypeScript handbook,

Because public is already the default visibility modifier, you don’t ever need to write it on a class member, but might choose to do so for style/readability reasons.

这显然是错误的。 Read函数在不指定publicprivateprotected时起作用,但Update函数仅在public、[=17=时起作用],或指定 protected

我会玩弄 CreateDelete。然后我会 post 关于这个 TypeScript 行为的另一个问题。