条件验证 Angular 2 - 模型驱动表单
Conditional Validation Angular 2 - Model Driven Forms
我在 Angular 2 中有一个表单,其中有一个复选框可以更改页面上的一些输入 [文本]。如果选中该复选框,名为 'CPF' 的输入将更改为 'CNPJ'。仅当复选框被选中时,我才需要 CNPJ,因为如果未选中,用户甚至不会看到 'CNPJ' 输入。
这是 HTML 代码的一个片段:
<div class="wrap-acordo">
<form [formGroup]="formDadosBancarios" novalidate class="" (ngSubmit)="enviarDados(formDadosBancarios.value)">
<div class="row">
<div class="col s12">
<label> Titular: </label>
<input type="text" formControlName="titular" name="titular" class="forms-econ" placeholder="Nome Completo do Titular">
<div class="div-validar">
<span [hidden]="formDadosBancarios.get('titular').hasError('required') || formDadosBancarios.controls.titular.valid || (formDadosBancarios.controls.titular.pristine && !submitted)">
Titular Inválido (mínimo 3 caracteres).
</span>
<span *ngIf="formDadosBancarios.get('titular').hasError('required') && submitted">
Campo titular obrigatório
</span><br>
</div>
</div>
<p class="check-margin">
<input type="checkbox" [checked]="" formControlName="pessoa_juridica" #checkJuridica (change)="handleType(checkJuridica.checked)" class="filled-in check-negociacao" id="pessoaJuridica" />
<label for="pessoaJuridica">Pessoa Jurídica</label>
</p>
<div *ngIf="checkJuridica.checked" class="col s12">
<label> CNPJ: </label>
<input type="text" formControlName="cnpj" name="cnpj" class="forms-econ" placeholder="Insira o CNPJ">
<div class="div-validar">
<span [hidden]="formDadosBancarios.get('cnpj').hasError('required') || formDadosBancarios.controls.cnpj.valid || (formDadosBancarios.controls.cnpj.pristine && !submitted)">
CNPJ inválido
</span>
<span *ngIf="formDadosBancarios.get('cnpj').hasError('required') && submitted">
CNPJ é obrigatório
</span><br>
</div>
</div>
<div *ngIf="!checkJuridica.checked" class="col s12 m6">
<label> CPF: </label>
<input type="text" formControlName="cpf" name="cpf" class="forms-econ" placeholder="Insira seu CPF">
<div class="div-validar">
<span [hidden]="formDadosBancarios.get('cpf').hasError('required') || formDadosBancarios.controls.cpf.valid || (formDadosBancarios.controls.cpf.pristine && !submitted)">
CPF inválido
</span>
<span *ngIf="formDadosBancarios.get('cpf').hasError('required') && submitted">
CPF é obrigatório
</span><br>
</div>
</div>
<div *ngIf="!checkJuridica.checked" class="col s12 m6">
<label> Data de Nascimento: </label>
<input type="text" class="forms-econ" formControlName="data_nasc" name="data_nasc" placeholder="ex.: Insira sua data de nascimento">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.data_nasc.valid || (formDadosBancarios.controls.data_nasc.pristine && !submitted)">
Data de nascimento é obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Banco: </label>
<input type="text" class="forms-econ" formControlName="banco" name="banco" placeholder="Banco">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.banco.valid || (formDadosBancarios.controls.banco.pristine && !submitted)">
Banco é um campo obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Agência: </label>
<input type="text" class="forms-econ" formControlName="agencia" name="agencia" placeholder="Agência">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.agencia.valid || (formDadosBancarios.controls.agencia.pristine && !submitted)">
Agência é um campo obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Conta: </label>
<input type="text" class="forms-econ" name="conta" formControlName="conta" placeholder="Conta">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.conta.valid || (formDadosBancarios.controls.conta.pristine && !submitted)">
Conta é um campo obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Tipo: </label>
<select name="tipo" formControlName="tipo" class="forms-econ">
<option value="motivo_01">Tipo 01</option>
<option value="motivo_02">Tipo 02</option>
</select>
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.tipo.valid || (formDadosBancarios.controls.tipo.pristine && !submitted)">
Tipo é um campo obrigatório
</span>
</div>
</div>
</div>
<div class="row center-align">
<div class="col s12 m6">
<input type="submit" class="botao-medio btn-aceita" value="Aceitar">
</div>
这里是组件代码的片段:
import { Component } from '@angular/core';
import {Http} from '@angular/http';
import { FormBuilder, FormGroup, Validators, FormArray, FormsModule, ReactiveFormsModule, AbstractControl, ValidatorFn } from '@angular/forms';
import {FinalizaNegociacaoService} from '../services/finaliza-negociacao.service';
import {dadosAcordo} from '../model/dados-acordo.interface';
@Component({
moduleId: module.id,
selector: 'detalhes',
templateUrl: `finaliza-negociacao.component.html`,
providers: [FinalizaNegociacaoService]
})
export class FinalizaNegociacaoComponent {
public dados:dadosAcordo;
public formDadosBancarios: FormGroup;
public submitted: boolean;
public events: any[] = [];
public servError:any;
public servSuccess:any;
cpf_REGEXP = /^\d+$/;
constructor(private _fb: FormBuilder, private finalizaAcordo:FinalizaNegociacaoService) { }
ngOnInit() {
this.formDadosBancarios = this._fb.group({
titular: ['', [<any>Validators.required, <any>Validators.minLength(3)]],
cpf: ['', [<any>Validators.required, Validators.pattern(this.cpf_REGEXP)]],
cnpj: ['', [<any>Validators.required, Validators.pattern(this.cpf_REGEXP)]],
data_nasc: ['', <any>Validators.required],
agencia: ['', <any>Validators.required ],
banco: ['', <any>Validators.required],
conta: ['', <any>Validators.required],
tipo: ['', <any>Validators.required],
id: ['']
})
}
enviarDados(model: dadosAcordo, isValid: boolean) {
this.submitted = true;
model.id = Math.floor((Math.random()*100));
if(this.formDadosBancarios.valid){
console.log("valid form")
this.finalizaAcordo.enviaDadosBancarios(model)
.subscribe(
res => console.log("Sucesso"),
error => console.log("ERRO")
);
}else{
console.log("invalid form")
}
}
有人可以帮助我吗?提前致谢:)
你的代码有点复杂,但我会给你提示,可能会帮助你解决问题。
无需在 cpf 或 cnpj 等条件字段上添加 validators.required
,否则您必须在复选框单击时触发的事件上添加验证。
如果您必须禁用提交按钮(在这种情况下,更好的做法是像这样 [disabled]=''checkValidation()
调用禁用属性中的函数并检查所有必填字段。
我希望这能对您的问题有所帮助,如果仍然不满意,请 post 完整代码或者在 plunker 上重现您的问题。
您可以执行以下操作:
- 创建一个方法来处理复选框的变化:
handleType(isJuridica: boolean): void {
const cpfCtrl: AbstractControl = this.formDadosBancarios.get('cpf');
const cnpjCtrl: AbstractControl = this.formDadosBancarios.get('cnpj');
const reqValidators: ValidatorFn[] = [Validators.required, Validators.pattern(this.cpf_REGEXP)];
const nullValidator: ValidatorFn = Validators.nullValidator;
// Set validators accordingly
if (isJuridica) {
cpfCtrl.setValidators(nullValidator);
cnpjCtrl.setValidators(reqValidators);
} else {
cpfCtrl.setValidators(reqValidators);
cnpjCtrl.setValidators(nullValidator);
}
// Clean values (if you want to)
cpfCtrl.patchValue('');
cnpjCtrl.patchValue('');
cpfCtrl.updateValueAndValidity();
cnpjCtrl.updateValueAndValidity();
}
- 在模板中调用:
...
<input type="checkbox" #checkJuridica (change)="handleType(checkJuridica.checked)" class="filled-in check-negociacao" id="pessoaJuridica" />
<label for="pessoaJuridica">Pessoa Jurídica</label>
...
您可以查看下面的简单演示:
另外还有这个tutorial可以帮助大家更好的理解
我在 Angular 2 中有一个表单,其中有一个复选框可以更改页面上的一些输入 [文本]。如果选中该复选框,名为 'CPF' 的输入将更改为 'CNPJ'。仅当复选框被选中时,我才需要 CNPJ,因为如果未选中,用户甚至不会看到 'CNPJ' 输入。
这是 HTML 代码的一个片段:
<div class="wrap-acordo">
<form [formGroup]="formDadosBancarios" novalidate class="" (ngSubmit)="enviarDados(formDadosBancarios.value)">
<div class="row">
<div class="col s12">
<label> Titular: </label>
<input type="text" formControlName="titular" name="titular" class="forms-econ" placeholder="Nome Completo do Titular">
<div class="div-validar">
<span [hidden]="formDadosBancarios.get('titular').hasError('required') || formDadosBancarios.controls.titular.valid || (formDadosBancarios.controls.titular.pristine && !submitted)">
Titular Inválido (mínimo 3 caracteres).
</span>
<span *ngIf="formDadosBancarios.get('titular').hasError('required') && submitted">
Campo titular obrigatório
</span><br>
</div>
</div>
<p class="check-margin">
<input type="checkbox" [checked]="" formControlName="pessoa_juridica" #checkJuridica (change)="handleType(checkJuridica.checked)" class="filled-in check-negociacao" id="pessoaJuridica" />
<label for="pessoaJuridica">Pessoa Jurídica</label>
</p>
<div *ngIf="checkJuridica.checked" class="col s12">
<label> CNPJ: </label>
<input type="text" formControlName="cnpj" name="cnpj" class="forms-econ" placeholder="Insira o CNPJ">
<div class="div-validar">
<span [hidden]="formDadosBancarios.get('cnpj').hasError('required') || formDadosBancarios.controls.cnpj.valid || (formDadosBancarios.controls.cnpj.pristine && !submitted)">
CNPJ inválido
</span>
<span *ngIf="formDadosBancarios.get('cnpj').hasError('required') && submitted">
CNPJ é obrigatório
</span><br>
</div>
</div>
<div *ngIf="!checkJuridica.checked" class="col s12 m6">
<label> CPF: </label>
<input type="text" formControlName="cpf" name="cpf" class="forms-econ" placeholder="Insira seu CPF">
<div class="div-validar">
<span [hidden]="formDadosBancarios.get('cpf').hasError('required') || formDadosBancarios.controls.cpf.valid || (formDadosBancarios.controls.cpf.pristine && !submitted)">
CPF inválido
</span>
<span *ngIf="formDadosBancarios.get('cpf').hasError('required') && submitted">
CPF é obrigatório
</span><br>
</div>
</div>
<div *ngIf="!checkJuridica.checked" class="col s12 m6">
<label> Data de Nascimento: </label>
<input type="text" class="forms-econ" formControlName="data_nasc" name="data_nasc" placeholder="ex.: Insira sua data de nascimento">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.data_nasc.valid || (formDadosBancarios.controls.data_nasc.pristine && !submitted)">
Data de nascimento é obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Banco: </label>
<input type="text" class="forms-econ" formControlName="banco" name="banco" placeholder="Banco">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.banco.valid || (formDadosBancarios.controls.banco.pristine && !submitted)">
Banco é um campo obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Agência: </label>
<input type="text" class="forms-econ" formControlName="agencia" name="agencia" placeholder="Agência">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.agencia.valid || (formDadosBancarios.controls.agencia.pristine && !submitted)">
Agência é um campo obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Conta: </label>
<input type="text" class="forms-econ" name="conta" formControlName="conta" placeholder="Conta">
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.conta.valid || (formDadosBancarios.controls.conta.pristine && !submitted)">
Conta é um campo obrigatório
</span>
</div>
</div>
<div class="col s12 m6">
<label> Tipo: </label>
<select name="tipo" formControlName="tipo" class="forms-econ">
<option value="motivo_01">Tipo 01</option>
<option value="motivo_02">Tipo 02</option>
</select>
<div class="div-validar">
<span [hidden]="formDadosBancarios.controls.tipo.valid || (formDadosBancarios.controls.tipo.pristine && !submitted)">
Tipo é um campo obrigatório
</span>
</div>
</div>
</div>
<div class="row center-align">
<div class="col s12 m6">
<input type="submit" class="botao-medio btn-aceita" value="Aceitar">
</div>
这里是组件代码的片段:
import { Component } from '@angular/core';
import {Http} from '@angular/http';
import { FormBuilder, FormGroup, Validators, FormArray, FormsModule, ReactiveFormsModule, AbstractControl, ValidatorFn } from '@angular/forms';
import {FinalizaNegociacaoService} from '../services/finaliza-negociacao.service';
import {dadosAcordo} from '../model/dados-acordo.interface';
@Component({
moduleId: module.id,
selector: 'detalhes',
templateUrl: `finaliza-negociacao.component.html`,
providers: [FinalizaNegociacaoService]
})
export class FinalizaNegociacaoComponent {
public dados:dadosAcordo;
public formDadosBancarios: FormGroup;
public submitted: boolean;
public events: any[] = [];
public servError:any;
public servSuccess:any;
cpf_REGEXP = /^\d+$/;
constructor(private _fb: FormBuilder, private finalizaAcordo:FinalizaNegociacaoService) { }
ngOnInit() {
this.formDadosBancarios = this._fb.group({
titular: ['', [<any>Validators.required, <any>Validators.minLength(3)]],
cpf: ['', [<any>Validators.required, Validators.pattern(this.cpf_REGEXP)]],
cnpj: ['', [<any>Validators.required, Validators.pattern(this.cpf_REGEXP)]],
data_nasc: ['', <any>Validators.required],
agencia: ['', <any>Validators.required ],
banco: ['', <any>Validators.required],
conta: ['', <any>Validators.required],
tipo: ['', <any>Validators.required],
id: ['']
})
}
enviarDados(model: dadosAcordo, isValid: boolean) {
this.submitted = true;
model.id = Math.floor((Math.random()*100));
if(this.formDadosBancarios.valid){
console.log("valid form")
this.finalizaAcordo.enviaDadosBancarios(model)
.subscribe(
res => console.log("Sucesso"),
error => console.log("ERRO")
);
}else{
console.log("invalid form")
}
}
有人可以帮助我吗?提前致谢:)
你的代码有点复杂,但我会给你提示,可能会帮助你解决问题。
无需在 cpf 或 cnpj 等条件字段上添加
validators.required
,否则您必须在复选框单击时触发的事件上添加验证。如果您必须禁用提交按钮(在这种情况下,更好的做法是像这样
[disabled]=''checkValidation()
调用禁用属性中的函数并检查所有必填字段。
我希望这能对您的问题有所帮助,如果仍然不满意,请 post 完整代码或者在 plunker 上重现您的问题。
您可以执行以下操作:
- 创建一个方法来处理复选框的变化:
handleType(isJuridica: boolean): void {
const cpfCtrl: AbstractControl = this.formDadosBancarios.get('cpf');
const cnpjCtrl: AbstractControl = this.formDadosBancarios.get('cnpj');
const reqValidators: ValidatorFn[] = [Validators.required, Validators.pattern(this.cpf_REGEXP)];
const nullValidator: ValidatorFn = Validators.nullValidator;
// Set validators accordingly
if (isJuridica) {
cpfCtrl.setValidators(nullValidator);
cnpjCtrl.setValidators(reqValidators);
} else {
cpfCtrl.setValidators(reqValidators);
cnpjCtrl.setValidators(nullValidator);
}
// Clean values (if you want to)
cpfCtrl.patchValue('');
cnpjCtrl.patchValue('');
cpfCtrl.updateValueAndValidity();
cnpjCtrl.updateValueAndValidity();
}
- 在模板中调用:
...
<input type="checkbox" #checkJuridica (change)="handleType(checkJuridica.checked)" class="filled-in check-negociacao" id="pessoaJuridica" />
<label for="pessoaJuridica">Pessoa Jurídica</label>
...
您可以查看下面的简单演示:
另外还有这个tutorial可以帮助大家更好的理解