Angular Reactive forms : change vs valueChanges

Posted

技术标签:

【中文标题】Angular Reactive forms : change vs valueChanges【英文标题】: 【发布时间】:2019-08-13 11:16:55 【问题描述】:

我在 Angular 7 中使用 reactive forms。

我有许多依赖于其他字段的字段。

我对@9​​87654322@或this.form.get("control_name").valueChanges应该使用什么感到好奇?

例如。如果两者都适用于输入,那么我想知道它们之间的区别、优缺点。

哪个性能更好?

【问题讨论】:

【参考方案1】:

让我们考虑一下,您正在寻找的是在 type="text"input 标签上收听更改

valueChanges的情况下

由于它是一个 Observable,它会以一个新值触发。此值将是 input 字段的更改值。要收听它,您必须将subscribe 发送到valueChanges Observable。像这样的:

this.form1.controls['name'].valueChanges.subscribe(change => 
  console.log(change); // Value inside the input field as soon as it changes
);

(change)事件的情况

change 事件的情况下,对于input 标记,change 事件只有在您blur 离开该input 字段时才会触发。此外,在这种情况下,您将获得 $event 对象。从那个$event 对象中,您必须提取字段值。


所以在代码中,这看起来像这样:

import  Component  from '@angular/core';
import  FormGroup, FormBuilder  from '@angular/forms';

@Component(...)
export class AppComponent  
  name = 'Angular';
  form1: FormGroup;
  form2: FormGroup;

  constructor(private fb: FormBuilder) 

  ngOnInit() 
    this.form1 = this.fb.group(
      name: [],
      email: []
    );

    this.form2 = this.fb.group(
      name: [],
      email: []
    );

    this.form1.controls['name'].valueChanges.subscribe(change => 
      console.log(change);
    );
  

  onForm2NameChange( target ) 
    console.log(target.value);
  


在模板中:

<form [formGroup]="form1">
  <input type="text" formControlName="name">
  <input type="text" formControlName="email">
</form>

<hr>

<form [formGroup]="form2">
  <input type="text" formControlName="name" (change)="onForm2NameChange($event)">
  <input type="text" formControlName="email">
</form>

这里有一个Working Sample StackBlitz 供您参考。


注意:这完全取决于您的用例,哪个更合适。


更新:

对于您的特定用例,我建议使用 RxJS 运算符来完成工作。像这样的:

zipCodeFormControl
  .valueChanges
  .pipe(
    debounceTime(500),
    distinctUntilChanged(),
    switchMap(
      zipcode => getAddressFromZipcode(zipcode)
    ),
    map(res => res.actualResult)
  )
  .subscribe(addressComponents => 
    // Here you can extract the specific Address Components
    // that you want to auto fill in your form and call the patchValue method on your form or the controls individually
  );

【讨论】:

这就是重点。此时我正在创建表单。我很困惑我应该使用什么。 根据目前的信息,我认为就性能而言,(change) 会更好,因为它只有在您离开场地时才会被调用 blur。但又一次。没有更具体的例子,很难确定。也许创建一个可以突出您面临的问题的示例,也许我可以提供更好的建议。 我只输入了 zip。在它发生变化时,我必须调用服务来获取州、国家、城市等数据...... @AnkurAkvaliya,我已经更新了我的答案。请检查这是否适用于您的用例。【参考方案2】:

这是个案,但我发现复选框和单选按钮(true/false 类型控件)与(更改)处理程序配合使用效果更好,输入和文本字段通常更适合 valueChanges。

虽然我不确定性能,但我认为这将是处理此决定时的理想用例。

valueChanges(适用于所有内容)的一个很好的用例是具有大量 ngIf 逻辑的复杂表单。有时这些表单需要值更改的“连锁反应”才能正常工作,在这种情况下,(更改)处理程序将无用

【讨论】:

【参考方案3】:

如果是输入(文本)字段,我建议根据您的用例使用changeValuesvalue

如果您想实现类似于“Google 的自动完成功能”的功能,即在您键入时提供(搜索)建议 → 请使用 changeValues。 对于其他情况,我会使用change

不过,这只是一个经验法则,魔鬼在细节中。

这是我在进行自己的研究/测试时编写的一个工作示例的代码,为了比较,它实现了这两种方法:

component html file component TypeScript file

【讨论】:

以上是关于Angular Reactive forms : change vs valueChanges的主要内容,如果未能解决你的问题,请参考以下文章

Angular Reactive Form 的一个具体使用例子

Angular Reactive Form 中的 DOB 验证

typescript 使用FormBuilder和AngularMaterial的Angular - Reactive Form

Angular Reactive forms : change vs valueChanges

Angular Reactive Form:无法设置未定义的属性

Angular Reactive Forms 重置值