Angular 5 反应式表单不会在 Firebase 上创建 ID 级别

Angular 5 Reactive form doesn't create ID level on Firebase

我有一个模板驱动的表单(使用 ngModel),我正在尝试将其更改为响应式表单。此表单将数据提交到 Firebase 数据库。

在(模板驱动的)数据正确插入 Firebase 之前,为每个发送的对象创建一个 ID,如下所示:

但是,当我改成Reactive形式时,有时插入的数据没有任何ID,如下所示:

发生这种情况时,我无法找出模式,也没有在代码中发现任何可以证明这种行为合理的错误。

service.component.html

 <form [formGroup]="f" (ngSubmit)="submit()">
    <input type="hidden" id="$key" formControlName="$key">
    <div class="form-group">
      <label for="nome">Name</label>
      <input type="text" class="form-control" id="nome" formControlName="nome">
    </div>
    <div class="row col-md-12">
      <div class="col-md-6">
        <div class="form-group">
          <label for="preco">Price</label>
          <input type="text" class="form-control" id="preco" formControlName="preco">
        </div>
      </div>

      <div class="col-md-6">
        <div class="form-group">
          <label for="tempo">Time</label>
          <input type="time" class="form-control" id="tempo" formControlName="tempo">
        </div>
      </div>
    </div>
    <br/>
    <button class="btn btn-success" type="submit" [disabled]="f?.invalid">Save</button>
  </form>

service.component.ts

import { Component, OnInit } from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable} from 'angularfire2/database';
import { Servico } from './servico';

export class ServiceComponent implements OnInit {

  f: FormGroup;

  userId: string;
  $key: string;
  value: any;
  servicos: FirebaseListObservable<Servico[]>;
  servico: FirebaseObjectObservable<Servico>;  

  constructor(private db: AngularFireDatabase, 
              private afAuth: AngularFireAuth,
              private fb: FormBuilder) { 

    this.afAuth.authState.subscribe(user => {
      if(user) this.userId = user.uid
        this.servicos = db.list(`servicos/${this.userId}`);
    })

  }

  ngOnInit() {
    this.f = this.fb.group({
      $key: new FormControl(''),
      nome: this.fb.control('', Validators.required),
      preco: this.fb.control(''),
      tempo: this.fb.control('')
    })
  }

  submit() {       
    if (this.f.controls.$key.value == null)
      {
        this.db.list(`servicos/${this.userId}/`).push({
          nome: this.f.controls.nome.value,
          preco: this.f.controls.preco.value,
          tempo: this.f.controls.tempo.value
        }).then(() => {
            this.f.controls.nome.setValue('');
            this.f.controls.preco.setValue('');
            this.f.controls.tempo.setValue('');
            this.f.controls.$key.setValue(null);
          });
        }else{
          this.db.object(`servicos/${this.userId}/` + this.f.controls.$key.value).update({
            nome: this.f.controls.nome.value,
            preco: this.f.controls.preco.value,
            tempo: this.f.controls.tempo.value
          }).then(() => {
            this.f.controls.nome.setValue('');
            this.f.controls.preco.setValue('');
            this.f.controls.tempo.setValue('');
            this.f.controls.$key.setValue(null);
          }));
        }
  }

}

我认为您的变量 this.f.controls.$key.value 被错误地设置为空字符串,这就是导致数据出现在错误位置的原因。由于空字符串不是 null 那么您的 if (this.f.controls.$key.value == null) 将是错误的,并且 else 将触发...

} else {
                                         // This is an empty string
                                                         \/  
                                                         \/  
    this.db.object(`servicos/${this.userId}/` + this.f.controls.$key.value).update({
      ...values...
    }).then(() => {
      ...etc...
    }));
  }

这意味着您的 update 呼叫实际上只是针对:

this.db.object(`servicos/${this.userId}/

要确认这是问题所在,请尝试在更新调用中硬编码一个值而不是 this.f.controls.$key.value,我怀疑奇怪的行为会消失。您需要找到另一种方法来获得正确的 key/path.