Angular 响应式表单:如何使用信息预加载表单输入

Angular Reactive Forms: how to pre load form inputs with information

我正在尝试在我的网站中创建一个论坛。在努力使用模板驱动的表单来实现之后,我决定切换到 Reactive 表单。我一直在我的站点中的两种方法之间切换,并意识到返回反应式表单的一个缺点导致我选择模板驱动的表单,我怀疑有一种解决方法值得弄清楚。我遇到的问题是,当用户想要编辑他们已经创建的内容时,我使用用于创建的相同表单,但将文档 ID 附加到路由,如下所示:

localhost:4200/create-thread/some-thread-uid

当遵循此路线时,它会加载创建线程组件,但会将已提供的数据预加载到适当的表单控件中。这是通过使用双向绑定将线程对象附加到相关表单的 ngModel 来实现的。像这样:

<!-- <form #finished="ngForm" (ngSubmit)="save(finished.value)">

<div class="form-group">
    <label for="author">Author of thread:</label>
        <input
            #author="ngModel"
            [(ngModel)]="thread.author"
            name="author"
            id="author"
            class="form-control"
            required
            type="text">                
    </div>
</form>

我的问题是,有没有一种方法可以使用 Reactive 表单来完成此操作(将已提供的信息从存储在云数据库中的对象加载到输入字段中进行编辑)?我尝试了几种方法但无法弄清楚,包括将 'thread.author' 注入表单构建器中的适当字段。 感谢您的帮助。

有两种方法可以完成您所说的操作,一种方法是在创建表单时填充字段,另一种方法是在创建表单后添加值。前者似乎适合您想在此处执行的操作,而后者则适合从计算值或服务调用的合并中构建表单。

在使用响应式表单做任何事情之前确保你已经在你的模块中导入了ReactiveFormsModule,像这样:

  imports: [
    ReactiveFormsModule
  ]

第一种方式 创建包含值的表单(即“编辑”)

首先,在component.ts中创建表单,如下所示:

export class YourEditComponent implements OnInit {

  // First you'll specify your form variable
  form: FormGroup;

  // In your constructor, be sure to inject FormBuilder
  constructor (private formBuilder: FormBuilder) {}

  // I like to create the form in OnInit, but for testing
  // purposes I prefer to call a function that creates the form,
  // rather than doing the logic in this function
  ngOnInit(): void {
    this.createEditFormGroup();
  }

  // Here's where you create your form. I assume you'll
  // be getting your form data object from a service, but
  // for the sake of demonstration I'll create the object here
  createEditFormGroup(): void {
    // Here you'll have the object already, so don't do this
    const thread = {
      author: 'breadman0',
      email: 'breadman0@gmail.com'
    }

    // Now simply create the form, passing this object (in this
    // case, the object "thread")
    this.form = this.formBuilder.group(thread);
  }

  // Now when you save, you don't need to pass in the value, you
  // can just access the form's value
  save(): void {
    console.log(this.form.value);
  }

}

在您的 component.html 中,您只需添加一些指令并处理“提交”事件。请参阅下面的 html,修改后可以正常工作:

<form [formGroup]="form" (ngSubmit)="save()">
    <div class="form-group">
        <label for="author">Author of thread:</label>
        <input
            formControlName="author"
            class="form-control"
            required
            type="text">                
    </div>
    <div class="form-group">
        <label for="email">Author's email:</label>
        <input
            formControlName="email"
            class="form-control"
            required
            type="text">                
    </div>
</form>

请注意,“必需”并不是很有用,因为它可以在 devtools 中修改。您最好按照表单中的要求设置字段。

第二种方式 用值填充现有表单

这种方式非常相似,只是我们只是用我们正在使用的任何对象的新实例创建表单

this.form = this.formBuilder.group({
  author: '',
  email: ''
});

//or

this.form = this.formBuilder.group(new Thread());

然后我们调用 patchValue:

// This can be done for any field in the form. I choose "author" here
this.form.patchValue({author: 'anonymous'});

看来我的问题其实与我的预期无关。出于某种原因,当我使用反应形式时,我从数据存储中获取的可观察 'thread' 是未定义的。我将用源代码创建第二个问题,希望有人能够发现我做错了什么。据我所知,无论是模板驱动形式还是响应式形式,一切形式方面的东西看起来都不错,而且我不确定为什么这会影响可观察到的加载或不以任何方式加载。同样,我订阅和访问 observable 的方式与任何一种实现都是相同的,所以我很困惑真正的问题是什么。