如何以编程方式触发`valueChanges`?

Max*_*Max 24 angular2-forms angular

在我的一个页面上,我使用a FormBuilder来填充初始化时的表单.只要输入不为空,每个输入都会获得一个类.这是通过ngClass在每个输入中添加一个并订阅的FormGroup来完成的valueChanges.

只要以编程方式填充表单,就会出现问题.每当用户更改表单上的任何值时,valueChanges都会被调用,但是,使用a时不是这种情况FormBuilder.

我的问题是:如何valueChangesFormBuilder完成时触发事件.

我尝试过使用this.FormGroup.updateValueAndValidity(),但这没有任何结果.

Max*_*Max 30

我找到了一个适合我的解决方案.我忘记了函数中的两个参数updateValueAndValidity.

  • onlySelf:只会FormControl在true时更新.
  • emiteEvent:会valueChanges在true时触发事件.

因此,您将得到类似的结果: FormGroup.updateValueAndValidity({ onlySelf: false, emitEvent: true });

  • 我总是忘记“ onlySelf”的作用。FormControl是子类的AbstractControl具有父属性。从docs中,如果onlySelf为true,则此更改将仅影响此FormControl的验证,而不影响其父组件。因此,默认情况下为false。因此,如果在窗体层次结构的“此”级别具有事件处理程序,则不会导致在父级上引发事件。 (2认同)
  • 请注意,这些是默认选项,因此您只需调用 [`.updateValueAndValidity()`](https://angular.io/api/forms/AbstractControl#updateValueAndValidity)。也许早期版本的 Angular 并非如此。 (2认同)

Sim*_*ver 11

您的问题不是100%清楚,但是我想您是在说什么:

当更改UI中的某些内容时,我的valueChanges可以正常工作,但是我想在完成构造函数中的FormBuilder对象的初始化以处理初始条件后立即触发我的订阅函数逻辑。

在这种情况下,我要做的很简单:

    this.searchForm.valueChanges
        .pipe(startWith(initialValues)).subscribe(value =>
        {
            // whatever you want to do here
        });
Run Code Online (Sandbox Code Playgroud)

initialValues是您用来初始化表单的原始数据。您可能也可以放进去searchForm.getRawValue()

这只会导致可观察对象立即射击。

  • 并确保取消订阅 (2认同)

Ang*_*hef 7

你的问题的标题和描述有点误导。是哪一个?(我)

  • 您想在以编程方式更改字段值时更新字段的有效性状态吗?
  • 或者您是否想确保valueChanges在以编程方式更改字段值时调用您对字段的订阅?

无论如何,看看这个 Plunkr:https://plnkr.co/edit/4V4PUFI1D15ZDWBfm2hb?p= preview

当您像这样以编程方式设置字段值时,您会看到:

this.myForm.get('myField').setValue(newValue);
Run Code Online (Sandbox Code Playgroud)

valueChanges该字段的有效性和可观测值均已更新。所以,看起来您正在尝试重新创建已经存在的行为。

但是,dirty以编程方式更改其值时,该字段的属性不会更新(根据文档:“如果用户更改了UI 中的值,则控件是脏的”)。难道您正在检查dirty属性以指示字段错误,并且您有一种错觉,认为有效性状态未更新,而实际上只是dirty属性未更新?

(一)这两件事是不同的。您不应该订阅valueChanges手动触发验证。应通过在表单模型中声明验证器来强制执行验证。

  • 谢谢你,麦克斯。但是如果你[查看`setValue()`的源代码](https://github.com/angular/angular/blob/master/modules/%40angular/forms/src/model.ts#L674)你'你会看到它已经调用了“updateValueAndValidity()”。此外,“emitEvent”参数默认设置为“true”。换句话说,默认行为应该已经为您提供了您想要的一切。也许您没有使用正确的语法以编程方式更改字段的值? (2认同)

xin*_*ose 6

我用来patchValue重置表单中的值并以编程方式触发更改:

this.MyForm.controls["MyField"].patchValue(MyField);

订阅更改:

this.MyForm.get("MyField").valueChanges.subscribe(val => {
    if (val) {
        const MyField = this.MyForm.get("MyField");
    }
});
Run Code Online (Sandbox Code Playgroud)