【问题标题】:Angular Reactive Forms: how to pre load form inputs with informationAngular Reactive Forms:如何使用信息预加载表单输入
【发布时间】:2021-03-02 16:46:00
【问题描述】:

我正在尝试在我的网站内创建一个论坛。在努力使用模板驱动的表单来实现之后,我决定切换到响应式表单。我在整个站点中一直在这两种方法之间切换,并意识到反应式表单有一个缺点,导致我选择模板驱动的表单,我怀疑有一种解决方法值得弄清楚。我遇到的问题是,当用户想要编辑他们已经创建的内容时,我使用与创建相同的表单,但将文档 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>

我的问题是,有没有办法使用响应式表单来实现这一点(将存储在云数据库中的对象中已经提供的信息加载到输入字段中进行编辑)?我尝试了几种方法但无法弄清楚,包括将“thread.author”注入表单构建器中的适当字段。 任何帮助表示赞赏。

【问题讨论】:

  • 有两种方法,一种是使用表单构建器注入它,即您提到的new FormControl(value, ...),另一种是使用FormControl.setValue(value)手动设置
  • 并且您可以在更改参数时使用Form.reset()清除表单,以避免在下一个id数据加载失败或promise仍处于未决状态时出现先前id的旧数据跨度>
  • @BeshambherChaukhwan 对于第二种解决方案,我会将这段代码放在组件的 setter 中的什么位置?不知道为什么,但使用 formbuilder 对我不起作用,我目前在我的代码中有它,当我打开一个线程进行编辑时,所有输入字段都是空的
  • 有人在下面回答了这个问题。请尝试一下。如果这不起作用,那么我会提出我的答案。您将在收到更新的数据并希望在表单中显示后立即设置该值。由于表单是响应式的,因此每当表单控件值发生变化时,它都会反映在表单中。现在什么时候做这取决于你的需要。

标签: angular angular-reactive-forms angular-template-form


【解决方案1】:

有两种方法可以执行您所说的操作,一种方法是在创建表单时填充字段,另一种方法是在创建表单后添加值。前者似乎适合您在这里想要做的事情,而后者则适用于根据计算值或服务调用的合并构建表单。

在对响应式表单进行任何操作之前确保您已在模块中导入 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'});

【讨论】:

  • 我将发布一个与此答案中提到的两点基本相同的答案:1)您可以在创建表单组时设置值 2)您可以稍后使用patchValue()。所以我创建了这个简单的StackBlitz 示例。也许它会帮助 OP。
【解决方案2】:

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

【讨论】:

  • 那么您的问题是首先将数据放入表单中?如果您像上面的示例一样创建一个模拟对象会发生什么?您的表单是否可以正常工作?
猜你喜欢
  • 2023-01-23
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 2021-06-07
  • 2023-03-04
  • 2020-12-26
  • 1970-01-01
相关资源
最近更新 更多