首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在我的角度项目中使用此反应性表单示例验证器规则似乎不起作用?

为什么在我的角度项目中使用此反应性表单示例验证器规则似乎不起作用?
EN

Stack Overflow用户
提问于 2020-08-23 17:09:22
回答 3查看 1.2K关注 0票数 2

我正在使用reactive 进行一个角度项目,我对表单验证策略有以下疑问。我会尽量详细解释我所做的事和我的问题。

在我的组件HTML代码中,我将这个表单(使用PrimeNG组件)放入:

代码语言:javascript
复制
<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字段(已注入构造函数):

代码语言:javascript
复制
projectForm: FormGroup;

然后,在组件ngOnInit()方法中,我定义了定义在HTML表单中的所有字段,以检索用户在表单输入字段中插入的值:

代码语言:javascript
复制
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中定义了一个带有事件的按钮,用于检索用户在表单中插入的值,如下所示:

代码语言:javascript
复制
<button pButton type="button" label="Save" icon="pi pi-check" (click)="saveOrder($event)"></button>

目前,saveOrder()方法仅打印已编译表单的值:

代码语言:javascript
复制
public saveOrder(event) {
    console.log("saveOrder() START");
    console.log(this.projectForm.value);
}

这似乎是可行的:单击保存按钮saveOrder()方法是call,我可以看到字段包含用户插入到form....untill中的值,现在似乎一切正常.

这个问题与验证程序有关。正如您现在看到的,我插入了相同的假规则来测试它(然后我将为我的所有字段创建特定的验证):

代码语言:javascript
复制
[Validators.required, Validators.minLength(5)]

基本上所有字段都是请求的,并且需要至少有5个字符的长度。因此,我希望,如果我不编译特定字段,或者插入一个由<5字符组成的值,则必须进入error...but,但情况并非如此。

事实上,例如,如果用户没有在我的表单中插入任何值并提交此表单,我就不会获得任何错误。简单地说,saveOrder()方法将在控制台中打印一个所有字段都为空的对象。

为什么?怎么啦?我遗漏了什么?我怎样才能解决这个问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-23 17:41:12

当您使用ReactiveForms时,角在后台做了一些事情。

在所有字段都生效之前,this.form.valid将是false。在提交表单时,这始终是首先要检查的事情。如果这是错误的,不要继续保存任何东西。如果将disabled="!form.valid"添加到按钮中,它将保持禁用状态,直到所有验证都通过为止。

无需在表单中填充任何内容,只需打开元素检查器并选择添加验证的控件。您应该看到它在class属性中添加了ng-无效的。您可以使用它突出显示使用CSS的错误字段。

例如:

代码语言:javascript
复制
 .ng-invalid { border: 1px solid red }

这种方法的背景是,它将显示错误,即使用户只是降落在页面。

因此,通常与之一起使用的还有另一个类ng触摸

代码语言:javascript
复制
.ng-touched.ng-invalid { ... }

它的问题是,只有当您访问该领域至少一次时,ng触摸才会被连接。为了能够使用它,您可以使用一个循环来遍历所有控件并以编程方式触摸它们。

还可以使用ngIf显示错误消息,只有在出现错误时才会显示。

例如:

代码语言:javascript
复制
<ng-container *ngIf="form.controls.get('idOrdine').errors">Error message</ng-container>

这最好与只在表单提交上设置的变量一起使用,这样页面第一次加载时就不会出现错误。

您可以查看控件,也可以在提交时查看表单实例,以便更清楚地了解表单中正在发生的事情。您可以找到很多方法来做同样的事情,但是解决方案只能由所需的行为来决定。

票数 2
EN

Stack Overflow用户

发布于 2020-08-23 17:12:23

我也面临着同样的问题。我把它修好了

代码语言:javascript
复制
ngNativeValidate

如下所示:-

代码语言:javascript
复制
<form ngNativeValidate [formGroup]="form" (ngSubmit)="onSubmit()">
票数 2
EN

Stack Overflow用户

发布于 2020-08-23 20:25:25

这就是表单在满足定义的验证条件之前仍然无效的预期行为,您需要添加自定义逻辑并在模板中显示正确的错误消息,并在表单生效之前阻止调用API。

代码语言:javascript
复制
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),您将看到所有控件及其属性,您可以注意到每个窗体控件的状态,即validtouchedpristinedirty 阅读更多

并且根据每个表单的控制状态,您可以显示相关的模板错误

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63549827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档