- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用响应式(Reactive)表单 开发一个 Angular 项目,我对表单验证策略有以下疑问。我将尝试详细解释我做了什么以及我的问题是什么。
在我的组件 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>
渲染这样的东西:
如您在上图和代码片段中所见,因为我有很多字段,所以我将这些字段分为 Accordion 项(但这应该不是问题)。
然后在我的组件 TypeScript 类中声明了这个 FormGroup 字段(我已经注入(inject)到我的构造函数中):
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()方法,我可以看到this.projectForm.value 字段包含用户插入到表单中的值....直到现在它似乎一切正常...
问题与验证 Angular 色有关。正如您目前看到的,我插入了相同的假规则来测试它(然后我将为我的所有字段创建特定的验证):
[Validators.required, Validators.minLength(5)]
基本上所有字段都是必需的,并且需要至少 5 个字符的长度。所以我预计如果我不编译一个特定的字段或者如果我插入一个由 <5 字符组成的值它必须进入错误...但事实并非如此。
事实上,例如,如果用户没有在我的表单中插入任何值并提交此表单,我就不会收到任何错误。 saveOrder() 方法会在控制台中打印一个所有字段都为空的对象。
为什么?怎么了?我错过了什么?我该如何解决这个问题?
最佳答案
当您使用 ReactiveForms 时,Angular 会在后台做一些事情。
在所有字段都变为有效之前,this.form.valid 将为false。这始终是提交表单时要检查的第一件事。如果这是错误的,请不要继续保存任何内容。如果您将 [disabled]="!form.valid" 添加到按钮,它将保持禁用状态,直到所有验证通过。
无需在表单中填写任何内容,只需打开元素检查器并选择已添加验证的控件。您应该看到它在类属性中添加了 ng-invalid。您可以使用它来使用 CSS 突出显示错误字段。
例如:
.ng-invalid { border: 1px solid red }
这个方法的背景是,即使用户刚登陆页面,它也会显示错误。
因此通常会使用另一个类 ng-touched。
.ng-touched.ng-invalid { ... }
它的问题是 ng-touched 只会在您访问该字段至少一次时才会附加。为了能够使用它,您可以使用循环遍历所有控件并以编程方式触摸它们。
也可以使用 ngIf 仅在出现错误时显示错误消息。
例如:
<ng-container *ngIf="form.controls.get('idOrdine').errors">Error message</ng-container>
这最好与仅在表单提交时设置的变量一起使用,这样错误就不会在页面首次加载时出现。
您可以查看控件,也可以在提交时查看表单实例,以更清楚地了解表单内部发生的情况。您可以找到很多方法来做同样的事情,但解决方案只能根据确切需要的行为来确定。
关于angular - 为什么验证器规则在我的 Angular 项目中使用这个响应式(Reactive)表单示例似乎不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63549827/
我刚刚更新了 Ruby,现在我在尝试启动 compass 时遇到以下错误: Encoding::CompatibilityError on line ["28"] of /usr/local/Cell
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 6 年前。
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在尝试在我的 iOS 应用程序中开发可折叠/ Accordion 式的功能。这将是您可以在网站上找到的典型 FAQ 类型功能。我想点击标题,然后显示详细信息。 因为这是帮助部分,只有几个项目,我认
我正在尝试设计一个基于 REST 的 Web 服务来与我正在开发的农场动物管理系统进行交互。 为了详细说明问题,我收藏了动物 属于一个农场。每只动物都有自己的信息——例如姓名、身份证号、品种年龄等。因
我有 3 种不同的表单,其中复选框数量不同,每个部分基本上代表一个表单,因此当用户选择该部分中的复选框时,它会显示他们在该部分的总金额中 checkout 了多少 HTML
我有一份 32 页的 PDF 版家谱。与其将家谱全部放在一个非常大的 PDF 页面上(这是我想要的),不如将其格式化为一组 8 个单独的美国信纸大小的页面应该在整个宽度上缝合; 4 行这样就完成了树。
指SASS implementation for Java? : 在 Maven 目标编译包中自动编译 compass-style.org 样式表的最佳方法是什么? 我不想发送太多的自编译库,也不想通
鉴于以下 XAML... 我正在寻找一种绑定(bind) ComboBox、Button 和 Command 的方法,以便当 ComboBox 的值更改时,在 Command 上调用 CanExe
在玩具应用程序中,我有一个显示所有帖子标题的“帖子”模板。当您单击每个标题时,我不想直接进入“显示” View ,而是直接内联展开该帖子的其余内容。 我考虑过让 postRoute 重用 postsR
我需要一些使用 Twitter Bootstrap 或其他响应式框架的自定义 Swagger-UI 实现。需要在我的移动设备上使用这样的 UI 测试我的 API,但 swagger-ui 不能很好地扩
我正在做一个项目,我真的在尝试编写面向对象的 JavaScript 代码。我刚刚开始阅读Douglas Crockford's JavaScript: The Good Parts我很快开始意识到用
在 C# 中,我通过执行以下操作来加密文本数据(请注意我正在以 block ( block )的形式加密数据): public string EncryptData(string pu
我正在构建一个社交网站,该网站将向全世界公开 REST API (WCF WebAPI),以便任何开发人员都能够为该网站创建客户端应用程序、将其与其他服务集成等。 我想为 API 实现 Faceboo
我是一名优秀的程序员,十分优秀!