简体   繁体   English

Angular 2:在填充所有字段之前,表单有效返回 false

[英]Angular 2: Form valid returns false until all fields are populated

I am using reactive forms.我正在使用反应形式。

I have a submit button that should be disabled until the form is valid:我有一个提交按钮,在表单有效之前应该禁用它:

<button type="submit" [disabled]="!_searchForm.valid && !_searchForm.pristine">Submit</button>

My fields can be toggled on/off using bools:可以使用 bool 打开/关闭我的字段:

showName: boolean = true;
showPhone: boolean = true;
showCellphone: boolean = true;

And this is my validation rules:这是我的验证规则:

this._searchForm = this._formBuilder.group({
    name: [{value: '', disabled: !this.showName}, Validators.compose([Validators.minLength(3), Validators.maxLength(50), Validators.pattern('^[a-zA-Z]+$')])],
    phone: [{value: '', disabled: !this.showPhone}, Validators.compose([Validators.minLength(3), Validators.maxLength(50), Validators.pattern('^[0-9-]+$')])],
    cellphone: [{value: '', disabled: !this.showCellphone}, Validators.compose([Validators.minLength(3), Validators.maxLength(50), Validators.pattern('^[0-9]+$')])]
});

And finally, this is how each field is displayed in the HTML:最后,这是每个字段在 HTML 中的显示方式:

<div class="form-group" [ngClass]="{'has-danger': _searchForm.controls.name.errors && !_searchForm.controls.name.pristine}">

<label for="name">Name:</label>

<div class="input-group">

    <span class="input-group-addon">
        <div class="onofwrapper">
            <div class="onoffswitch">
                <input id="toggleName" type="checkbox" class="onoffswitch-checkbox" (click)='toggleName()' [checked]="showName">
                <label class="onoffswitch-label" for="toggleName"></label>
            </div>
        </div>
    </span>

    <input type="text" formControlName="name" class="form-control" [ngClass]="{'form-control-danger': _searchForm.controls.name.errors && !_searchForm.controls.name.pristine}" autocomplete="off" spellcheck="false">

</div>

<div *ngIf="_searchForm.controls.name.errors && !_searchForm.controls.name.pristine" class="form-control-feedback">Error message</div>

If I don't touch the form I can submit, so pristine seems to be working.如果我不触摸我可以提交的表格,那么pristine似乎正在起作用。

The problem is, I can't enter text in just a single field and submit.问题是,我无法在单个字段中输入文本并提交。 If I enter text in one field, I have to enter text in all of them to be able to submit, or else _searchForm.valid won't return true even though I am not using Validators.required on all fields.如果我在一个字段中输入文本,我必须在所有字段中输入文本才能提交,否则即使我没有在所有字段上使用Validators.required_searchForm.valid也不会返回 true。

I have verified that each input "ships its own value", by removing the [disabled="!_searchForm.valid" line, and then just dumping out the values in my submit function like this:我已经通过删除[disabled="!_searchForm.valid"行来验证每个输入“传送自己的值”,然后像这样在我的提交函数[disabled="!_searchForm.valid"储值:

console.log('Name: ' + this._searchForm.value.name);
console.log('Phone: ' + this._searchForm.value.phone);
console.log('Cellphone: ' + this._searchForm.value.cellphone);

What am I doing wrong?我做错了什么? Why does .valid require all fields in the form?为什么.valid要求表单中的所有字段?

If you disable or enable an input, then, you need a function:如果禁用或启用输入,则需要一个函数:

enableDisableInput(inputName: string): void {
    if(!this._searchForm.controls[inputName].disabled) {
        this._searchForm.controls[inputName].clearValidators();
        this._searchForm.controls[inputName].disable();
    } else {
    this._searchForm.controls[inputName].setValidators(Validators.compose([Validators.minLength(3), Validators.maxLength(50), Validators.pattern('^[0-9]+$')])]);
    }
    this._searchForm.controls[inputName].updateValueAndValidity();
}

Invoked <input id="toggleName" type="checkbox" class="onoffswitch-checkbox" (click)='enableDisableInput("name")' [checked]="showName">调用<input id="toggleName" type="checkbox" class="onoffswitch-checkbox" (click)='enableDisableInput("name")' [checked]="showName">

The manner in which the form building and validation is done with Reactive Forms means that you must manually clear and add validation even on disabled items (there may be plans to change this as it is a not uncommon complaint on the angular github).使用 Reactive Forms 完成表单构建和验证的方式意味着您必须手动清除和添加即使在禁用项目上的验证(可能有计划改变这一点,因为这在 angular github 上并不少见)。 This is a code oriented and driven manner of forms and needs to be treated as such for the time being.这是一种面向代码和驱动的表单方式,暂时需要这样对待。

Whether or not the inputs are required is moot if they have an unmet minimum length.如果输入具有未满足的最小长度,则是否需要输入是没有意义的。 Reference https://github.com/angular/angular/pull/11450 which was recently included in Angular 2.0.2 https://github.com/angular/angular/blob/master/CHANGELOG.md参考https://github.com/angular/angular/pull/11450 ,最近包含在 Angular 2.0.2 https://github.com/angular/angular/blob/master/CHANGELOG.md

For forms driven it looks like they have a correction in 2.1.0 where those fields are optional with pattern and minlength but I don't know if that's also in Reactive Forms or not.对于驱动的表单,看起来它们在 2.1.0 中有一个更正,其中这些字段是可选的,带有模式和最小长度,但我不知道这是否也在响应式表单中。

It turns out that this was a problem with input type="number" .事实证明,这是input type="number" The fields containing phone and cellphone values was only supposed to contain numbers, so in addition to the Validators.pattern('^[0-9-]+$') validation I also gave them the input type of number.包含电话和手机值的字段应该只包含数字,所以除了Validators.pattern('^[0-9-]+$')验证我还给了他们输入类型的数字。

As soon as that was changed into text, everything worked like expected.一旦将其更改为文本,一切都按预期进行。

I had the same issue with the Angular reactive forms.我对 Angular 反应形式有同样的问题。 I was disabling and enabling my form controls based on some logic.我根据某些逻辑禁用和启用我的表单控件。 It turns out I was disabling, but not enabling back the form controls, so I was getting a form.valid as false.结果是我禁用了表单控件,但没有启用表单控件,所以我得到的 form.valid 为 false。 Apparently in Angular's reactive forms a form with disabled fields is invalid and the docs are not mentioning this default behavior.显然,在 Angular 的响应式表单中,带有禁用字段的表单是无效的,并且 文档没有提到这种默认行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM