Почему эта угловая форма остается в недопустимом состоянии после того, как я ее полностью заполнил?

#angular #primeng #angular-reactive-forms #angular-forms

#угловая #primeng #angular-reactive-forms #angular-forms

Вопрос:

Я работаю над приложением Angular с использованием PrimeNG, и у меня следующая проблема с формой.

Когда я заполняю форму, она также остается в недопустимом состоянии, если выполняются все правила проверки.

Это мой компонентный HTML-вид:

 <p-dialog header="Inserire un nuovo asset"
          maximizable="true"
          [(visible)]="displayNewAssetDialog"
          (onHide)="closeDialog()"
          position="top"
          [style]="{width: '50vw'}">

        <form [formGroup]="newAssetForm" id="addAssetForm" (ngSubmit)=saveNewAsset()>

            <div class="row">
                <div class="col-2">
                  <p>Tipo asset</p>
                </div>
                <div class="col-10">
                  <p-dropdown id="assetType"
                              [options]="assetTypeList" 
                              [(ngModel)]="selectedAssetTypeNg" 
                              formControlName="asset_type"
                              placeholder="Tipo asset" 
                              optionLabel="type" 
                              [showClear]="true">
                  </p-dropdown>
                </div>
              </div>

              <div class="row">
                <div class="col-2">
                  <p>Modello</p>
                </div>
                <div class="col-10">
                    <input id="assetModel" formControlName="asset_model" type="text" pInputText />
                </div>
              </div>
              <!--
              <div class="row">
                <div class="col-2">
                  <p>Assegnato a</p>
                </div>
                <div class="col-10">
                  <p-dropdown id="employee_allocation"
                              [options]="employeesList$ | async" 
                              formControlName="employee_allocation"
                              placeholder="Impiegato" 
                              optionLabel="completeName" 
                              [showClear]="true">
                  </p-dropdown>
                </div>
              </div>
            -->
            

              <div class="row">
                <div class="col-2">
                  <p>Caratteristiche</p>
                </div>
                <div class="col-10">
                    <textarea id="assetFeatures" 
                              class="p-inputtextarea"
                              formControlName="asset_features" 
                              [rows]="5" [cols]="30" 
                              pInputTextarea 
                              autoResize="autoResize">
                    </textarea>
                </div>
              </div>

              <div class="row">
                <div class="col-2">
                  <p>Serial Number</p>
                </div>
                <div class="col-10">
                    <input id="serialNumber" formControlName="serial_number" type="text" pInputText />
                </div>
              </div>


              <div class="row">
                <div class="col-2">
                  <p>Data di consegna</p>
                </div>
                <div class="col-10" [ngClass]="{'ng-pristine ng-invalid ng-touched': isEmptyDate}">
                  <p-calendar [ngClass]="{'invalid-date': isValidDate}"
                              id="allocationDate" 
                              inputId="allocationDate"
                              formControlName="allocation_date"
                              >
                  </p-calendar>
                </div>
              </div>

              <div class="row">
                <div class="col-2">
                  <p>company</p>
                </div>
                <div class="col-10">
                    <input id="company" formControlName="company" type="text" pInputText />
                </div>
              </div>

              <div class="row">
                <div class="col-2">
                  <p>Note</p>
                </div>
                <div class="col-10">
                    <textarea id="notes" 
                              class="p-inputtextarea"
                              formControlName="notes" 
                              [rows]="5" [cols]="30" 
                              pInputTextarea 
                              autoResize="autoResize">
                    </textarea>
                </div>
              </div>

              <div class="row">
                <div class="col-2">
                  <p>Fattura/Provenienza</p>
                </div>
                <div class="col-10">
                    <textarea id="invoice" 
                              class="p-inputtextarea"
                              formControlName="invoice" 
                              [rows]="5" [cols]="30" 
                              pInputTextarea 
                              autoResize="autoResize">
                    </textarea>
                </div>
              </div>

              <p-footer>
                <span class="p-buttonset">
                  <button pButton 
                          type="submit"
                          label="Save" 
                          icon="pi pi-check"
                          [disabled]="!newAssetForm.valid">

                  </button>
                  <button pButton type="button" label="Cancel" icon="pi pi-times" (click)="closeDialog()"></button>
              </span>
              </p-footer>

              <p>{{newAssetForm.valid}}</p>
              <p>{{newAssetForm.status | json }}</p>
              <p>{{newAssetForm.value | json }}</p>
        </form>
</p-dialog>
 

Как вы можете видеть в конце этого файла, я добавил несколько тегов абзацев, содержащих информацию о состоянии формы, для целей отладки. Вы также можете видеть, что кнопки отправки отключены, когда форма находится в недопустимом состоянии.

Тогда это машинописный код моего компонента:

 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { AssetService } from 'src/app/services/asset.service';
import { EmployeeService } from 'src/app/services/employee.service';
import { Employee } from 'src/app/shared/interfaces/employee';

@Component({
  selector: 'app-asset-add-form',
  templateUrl: './asset-add-form.component.html',
  styleUrls: ['./asset-add-form.component.scss']
})
export class AssetAddFormComponent implements OnInit {

  @Input()
  displayNewAssetDialog: boolean;

  @Output()
  onDialogClose: EventEmitter<any> = new EventEmitter(); 

  newAssetForm: FormGroup;
  
  assetTypeList: any[];
  selectedAssetTypeNg: any;
  isValidDate: boolean;
  isEmptyDate: true;
  loading: boolean = true;

  employeesList$:Observable<Employee[]>;

  constructor(private fb: FormBuilder,
              private employeeService: EmployeeService,
              private assetService: AssetService) { }

  ngOnInit(): void {
    console.log("AssetAddFormComponent INIT");

    this.assetTypeList = [
      {type: 'Notebook', code: 'NB' },
      {type: 'Notebook cliente', code: 'NB-C' },
      {type: 'Smartphone', code: 'SP' },
      {type: 'Drive', code: 'DRV' },
      {type: 'Licenza Office 2016', code: 'LO-2016' },
      {type: 'Licenza Office 2019', code: 'LO-2019' },
      {type: 'Licenza Office 2019 Professional', code: 'LO-2019-P' },
      {type: 'Licenza Office Plus 2019 Professional', code: 'LO-P-2019-P' },
      {type: 'RAM', code: 'RAM' },
      {type: 'Monitor', code: 'MON' },
      {type: 'Muletto', code: 'MUL' },
      {type: 'SIM', code: 'SIM' }
    ];

    this.loadEmployeesList().then(() => {this.loading = false;})

    this.newAssetForm = this.fb.group({
      asset_type: [null, [Validators.required]],
      asset_model: [null, [Validators.required]],
      //employee_allocation: [null],
      asset_features: [null, [Validators.required]],
      serial_number: [null, [Validators.required]],
      accessories: [null, [Validators.required]],
      allocation_date: [null, [Validators.required]],
      company: [null, [Validators.required]],
      notes: [null, [Validators.required]],
      invoice: [null, [Validators.required]]

    });
  }

  closeDialog() {
    console.log("CHILD COMPONENT closeDialog() START");
    this.onDialogClose.emit();
  }

  // Load the list of all the employees:
  async loadEmployeesList() {
    this.employeesList$ = await this.employeeService.getAllEmployees()
    console.log("employeesList$: ", this.employeesList$);
  }

  async saveNewAsset(){
    console.warn("saveNewAsset()",this.newAssetForm.value);    
    
    let parameters = {      
      firstName: this.newAssetForm.value.a,
      surname: this.newAssetForm.value.surname,      
      placeOfBirth: this.newAssetForm.value.placeOfBirth,
      socialSecurityCode: this.newAssetForm.value.socialSecurityCode,
      birthDate: this.newAssetForm.value.birthDate,
      companyEmail: this.newAssetForm.value.companyEmail,
      personalEmail: this.newAssetForm.value.personalEmail,     
      companyPhone: this.newAssetForm.value.companyPhone,  
      personalPhone: this.newAssetForm.value.personalPhone,  
      selectedEmployeeStatus: this.newAssetForm.value.selectedEmployeeStatus
    }

    if(this.newAssetForm.value.employee_allocation)
      parameters["employee_allocation"] = this.newAssetForm.value.employee_allocation;

    await this.assetService.saveAsset(parameters);
  }

}
 

Проблема в том, что после того, как я заполнил свою форму, она все еще находится в недопустимом состоянии. Это информация, напечатанная на странице тегами предыдущих абзацев отладки:

 false

"INVALID"

{ "asset_type": { "type": "Notebook", "code": "NB" }, "asset_model": "ASUS X509JA-EJ026T ", "asset_features": "test1", "serial_number": "123xxx", "accessories": null, "allocation_date": "2020-12-26T23:00:00.000Z", "company": "Technology", "notes": "test2", "invoice": "test3" }
 

Как вы можете видеть, форма кажется идеально заполненной, но она остается в недопустимом состоянии.

Это экран печати:

введите описание изображения здесь

Почему? Чего мне не хватает? Что не так? Как я могу решить проблему? Как я могу проверить, какова точная ошибка в форме? (Я полагаю, что, возможно, с помощью deubugger я могу увидеть, какие поля вводятся с ошибкой, или я могу распечатать эти ошибки)

Комментарии:

1. не могли бы вы предоставить работоспособную демонстрационную версию stackblitz для игры? 🙂

Ответ №1:

Я вижу, что вы объявили элемент управления формой с именем «аксессуары», например (аксессуары: [null, [Validators.required]]) в вашей группе форм, который является «обязательным», однако вы не использовали его в своем html, что приводит к постоянному нулевому значению, которое является значением по умолчанию, которое вы указали.

Что вы можете сделать, это добавить еще одну запись в свою форму, например:

 <div class="col-10">
   <input id="accessories" formControlName="accessories" type="text" pInputText />
</div>
 

затем попробуйте ввести какое-нибудь случайное значение, чтобы проверить это.