我正在使用reactive 进行一个角度项目,我对表单验证策略有以下疑问。我会尽量详细解释我所做的事和我的问题。
在我的组件HTML代码中,我将这个表单(使用PrimeNG组件)放入:
<form [formGroup]="projectForm">
<p-accordion [multiple]="true">
<p-accordionTab header="Informazioni generali ordine">
<div id="informazioni_generale_ordine">
<div class="row">
<div class="col-2">
<p>ID Ordine</p>
</div>
<div class="col-10">
<p-inputNumber id="idOrdine" formControlName="idOrdine"></p-inputNumber>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Data inserimento ordine</p>
</div>
<div class="col-10">
<p-calendar id="dataInserimentoOrdine" formControlName="dataInserimentoOrdine"></p-calendar>
</div>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Stato ordine</p>
</div>
<div class="col-10">
<input id="statoOrdine" formControlName="statoOrdine" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Commessa</p>
</div>
<div class="col-10">
<input id="commessa" formControlName="commessa" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>CIG</p>
</div>
<div class="col-10">
<input id="CIG" formControlName="CIG" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Data inizio attività</p>
</div>
<div class="col-10">
<p-calendar id="dataInizioAttivita" formControlName="dataInizioAttivita"></p-calendar>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Data fine attività</p>
</div>
<div class="col-10">
<p-calendar id="dataFineAttivita" formControlName="dataFineAttivita"></p-calendar>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Referente</p>
</div>
<div class="col-10">
<input id="referente" formControlName="referente" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Ruolo referente</p>
</div>
<div class="col-10">
<input id="ruoloReferente" formControlName="ruoloReferente" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Tipologia di partecipazione</p>
</div>
<div class="col-10">
<input id="tipologiaDiPartecipazione" formControlName="tipologiaDiPartecipazione" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Quota percentuale di RTI</p>
</div>
<div class="col-10">
<p-inputNumber id="quotaPercentualeDiRTI" formControlName="quotaPercentualeDiRTI" suffix="%"></p-inputNumber>
</div>
</div>
</p-accordionTab>
<p-accordionTab header="Informazioni cliente">
<div id="informazioni_cliente">
<div class="row">
<div class="col-2">
<p>Cliente</p>
</div>
<div class="col-10">
<input id="cliente" formControlName="cliente" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Partita IVA cliente</p>
</div>
<div class="col-10">
<input id="vatCliente" formControlName="vatCliente" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Cliente finale</p>
</div>
<div class="col-10">
<input id="clienteFinale" formControlName="clienteFinale" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Partita IVA cliente finale</p>
</div>
<div class="col-10">
<input id="vatClienteFinale" formControlName="vatClienteFinale" type="text" pInputText />
</div>
</div>
</div>
</p-accordionTab>
<p-accordionTab header="Informazioni contratto">
<div id="informazioni_contratto">
<div class="row">
<div class="col-2">
<p>Tipologia contratto</p>
</div>
<div class="col-10">
<input id="tipologiaContratto" formControlName="tipologiaContratto" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Importo contratto</p>
</div>
<div class="col-10">
<p-inputNumber id="importoContratto" formControlName="importoContratto" mode="currency" currency="EUR" locale="de-DE"></p-inputNumber>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Link Contratto</p>
</div>
<div class="col-10">
<input id="linkContratto" formControlName="linkContratto" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Data sottoscrizione contratto</p>
</div>
<div class="col-10">
<p-calendar id="dataSottoscrizioneContratto" formControlName="dataSottoscrizioneContratto"></p-calendar>
</div>
</div>
</div>
</p-accordionTab>
<p-accordionTab header="Informazioni società">
<div id="informazioni_societa">
<div class="row">
<div class="col-2">
<p>Nome Società</p>
</div>
<div class="col-10">
<input id="nomeSocieta" formControlName="nomeSocieta" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Partita IVA Società</p>
</div>
<div class="col-10">
<input id="vatSocieta" formControlName="vatSocieta" type="text" pInputText/>
</div>
</div>
<div class="row">
<div class="col-2">
<p>BU</p>
</div>
<div class="col-10">
<input id="bu" formControlName="bu" type="text" pInputText />
</div>
</div>
</div>
</p-accordionTab>
<p-accordionTab header="Informazioni accordo quadro">
<div id="informazioni_accordo_quadro">
<div class="row">
<div class="col-2">
<p>Presenza accordo quadro</p>
</div>
<div class="col-10">
<p-selectButton [options]="presenzaAQOption" id="presenzaAQ" formControlName="presenzaAQ" ></p-selectButton>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Link identificatovo accordo quadro</p>
</div>
<div class="col-10">
<input id="linkIdentificativoAQ" formControlName="linkIdentificativoAQ" type="text" pInputText />
</div>
</div>
<div class="row">
<div class="col-2">
<p>Accordo quadro</p>
</div>
<div class="col-10">
<p-inputNumber id="accordoQaudro" formControlName="accordoQaudro" mode="currency" currency="EUR" locale="de-DE" ></p-inputNumber>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Residuo accordo quadro</p>
</div>
<div class="col-10">
<p-inputNumber id="residuoAccordoQaudro" formControlName="residuoAccordoQaudro" mode="currency" currency="EUR" locale="de-DE"></p-inputNumber>
</div>
</div>
<div class="row">
<div class="col-2">
<p>Compagine di accordo quadro</p>
</div>
<div class="col-10">
<input id="compagineDiAQ" formControlName="compagineDiAQ" type="text" pInputText />
</div>
</div>
</div>
</p-accordionTab>
</p-accordion>
</form>呈现如下内容:

正如您在前面的图像和代码片段中所看到的,因为我有很多字段,所以我将这些字段划分为一个手风琴项目(但这应该不是问题)。
然后,在我的组件TypeScript类中,我声明了这个FormGroup字段(已注入构造函数):
projectForm: FormGroup;然后,在组件ngOnInit()方法中,我定义了定义在HTML表单中的所有字段,以检索用户在表单输入字段中插入的值:
ngOnInit() {
this.projectForm = this.fb.group({
idOrdine: [null, [Validators.required, Validators.minLength(5)]],
dataInserimentoOrdine: [null, [Validators.required, Validators.minLength(5)]],
statoOrdine: [null, [Validators.required, Validators.minLength(5)]],
commessa: [null, [Validators.required, Validators.minLength(5)]],
CIG: [null, [Validators.required, Validators.minLength(5)]],
dataInizioAttivita: [null, [Validators.required, Validators.minLength(5)]],
dataFineAttivita: [null, [Validators.required, Validators.minLength(5)]],
referente: [null, [Validators.required, Validators.minLength(5)]],
ruoloReferente: [null, [Validators.required, Validators.minLength(5)]],
tipologiaDiPartecipazione: [null, [Validators.required, Validators.minLength(5)]],
quotaPercentualeDiRTI: [null, [Validators.required, Validators.minLength(5)]],
cliente: [null, [Validators.required, Validators.minLength(5)]],
vatCliente: [null, [Validators.required, Validators.minLength(5)]],
clienteFinale: [null, [Validators.required, Validators.minLength(5)]],
vatClienteFinale: [null, [Validators.required, Validators.minLength(5)]],
tipologiaContratto: [null, [Validators.required, Validators.minLength(5)]],
importoContratto: [null, [Validators.required, Validators.minLength(5)]],
linkContratto: [null, [Validators.required, Validators.minLength(5)]],
dataSottoscrizioneContratto: [null, [Validators.required, Validators.minLength(5)]],
nomeSocieta: [null, [Validators.required, Validators.minLength(5)]],
vatSocieta: [null, [Validators.required, Validators.minLength(5)]],
bu: [null, [Validators.required, Validators.minLength(5)]],
presenzaAQ: [null, [Validators.required, Validators.minLength(5)]],
linkIdentificativoAQ: [null, [Validators.required, Validators.minLength(5)]],
accordoQaudro: [null, [Validators.required, Validators.minLength(5)]],
residuoAccordoQaudro: [null, [Validators.required, Validators.minLength(5)]],
compagineDiAQ: [null, [Validators.required, Validators.minLength(5)]]
});最后,我在HTML中定义了一个带有事件的按钮,用于检索用户在表单中插入的值,如下所示:
<button pButton type="button" label="Save" icon="pi pi-check" (click)="saveOrder($event)"></button>目前,saveOrder()方法仅打印已编译表单的值:
public saveOrder(event) {
console.log("saveOrder() START");
console.log(this.projectForm.value);
}这似乎是可行的:单击保存按钮saveOrder()方法是call,我可以看到字段包含用户插入到form....untill中的值,现在似乎一切正常.
这个问题与验证程序有关。正如您现在看到的,我插入了相同的假规则来测试它(然后我将为我的所有字段创建特定的验证):
[Validators.required, Validators.minLength(5)]基本上所有字段都是请求的,并且需要至少有5个字符的长度。因此,我希望,如果我不编译特定字段,或者插入一个由<5字符组成的值,则必须进入error...but,但情况并非如此。
事实上,例如,如果用户没有在我的表单中插入任何值并提交此表单,我就不会获得任何错误。简单地说,saveOrder()方法将在控制台中打印一个所有字段都为空的对象。
为什么?怎么啦?我遗漏了什么?我怎样才能解决这个问题?
发布于 2020-08-23 17:41:12
当您使用ReactiveForms时,角在后台做了一些事情。
在所有字段都生效之前,this.form.valid将是false。在提交表单时,这始终是首先要检查的事情。如果这是错误的,不要继续保存任何东西。如果将disabled="!form.valid"添加到按钮中,它将保持禁用状态,直到所有验证都通过为止。
无需在表单中填充任何内容,只需打开元素检查器并选择添加验证的控件。您应该看到它在class属性中添加了ng-无效的。您可以使用它突出显示使用CSS的错误字段。
例如:
.ng-invalid { border: 1px solid red }这种方法的背景是,它将显示错误,即使用户只是降落在页面。
因此,通常与之一起使用的还有另一个类ng触摸。
.ng-touched.ng-invalid { ... }它的问题是,只有当您访问该领域至少一次时,ng触摸才会被连接。为了能够使用它,您可以使用一个循环来遍历所有控件并以编程方式触摸它们。
还可以使用ngIf显示错误消息,只有在出现错误时才会显示。
例如:
<ng-container *ngIf="form.controls.get('idOrdine').errors">Error message</ng-container>这最好与只在表单提交上设置的变量一起使用,这样页面第一次加载时就不会出现错误。
您可以查看控件,也可以在提交时查看表单实例,以便更清楚地了解表单中正在发生的事情。您可以找到很多方法来做同样的事情,但是解决方案只能由所需的行为来决定。
发布于 2020-08-23 17:12:23
我也面临着同样的问题。我把它修好了
ngNativeValidate如下所示:-
<form ngNativeValidate [formGroup]="form" (ngSubmit)="onSubmit()">发布于 2020-08-23 20:25:25
这就是表单在满足定义的验证条件之前仍然无效的预期行为,您需要添加自定义逻辑并在模板中显示正确的错误消息,并在表单生效之前阻止调用API。
public saveOrder() {
// if form is invalid do not do any action.
if (this.projectForm.invalid) {
return
}
// call api or whatever your logic once form is submitted with valid data.
}如果您打印console.log(this.projectForm.controls),您将看到所有控件及其属性,您可以注意到每个窗体控件的状态,即valid、touched、pristine、dirty 阅读更多。
并且根据每个表单的控制状态,您可以显示相关的模板错误。
https://stackoverflow.com/questions/63549827
复制相似问题