#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>
затем попробуйте ввести какое-нибудь случайное значение, чтобы проверить это.