angular - Hur man effektivt hanterar två kategorier av kontroller på ett formulär?
På ett formulär har jag två (eller fler) kategorier av kontroller (för närvarande endast kryssrutor):
<form [formGroup]="form">
<div class="category 1">
<mat-checkbox formControlName="cb1">Checkbox 1</mat-checkbox>
<mat-checkbox formControlName="cb2">Checkbox 2</mat-checkbox>
</div>
<div class="category 2">
<mat-checkbox formControlName="cb11">Checkbox 11</mat-checkbox>
<mat-checkbox formControlName="cb12">Checkbox 12</mat-checkbox>
</div>
...
</form>
Beroende på andra åtgärder på formuläret behöver jag kontrollera tillståndet för en kategori, det vill säga aktivera/inaktivera och markera/avmarkera alla kontroller. Så jag behöver ett sätt att effektivt iterera över en kategori. För närvarande har jag kommit på en lösning baserad på detta svar, men detta kräver att man upprätthåller listor med namn för varje kategori.
Finns det ett trevligare/enklare sätt att iterera över mina kategorier?
Svar #1
Hög nivå - FormGroup-typen har en controls-egenskap som är ett objekt av följande typ {[key: string]: AbstractControl}, se Angular-dokumentationen.
Tekniskt sett kan du iterera över objektets egenskaper med for (const key in obj)-konstruktionen och manipulera dina formulärkontroller.
Enligt Angular-dokumentationen kan du nästla FormGroup-komponenter för att skapa den struktur du behöver för att bättre hantera kontrollernas beteende.
Svar #2
Om jag förstår din fråga rätt behöver du bara aktivera/inaktivera och markera/avmarkera kryssrutan baserat på villkor, eller hur?
Du kan göra något liknande direkt i HTML
<mat-checkbox> har [disabled] och [checked] attribut i sitt API. Du kan använda det.
Du kan använda *ngIf för att styra villkoren.
Det kommer att bli något som detta:
<form [formGroup]="someForm"> // Don't name your form as 'form'. Not a good practice
<div class="category 1">
<mat-checkbox formControlName="cb1">Checkbox 1</mat-checkbox>
<mat-checkbox formControlName="cb2">Checkbox 2</mat-checkbox>
</div>
// Enable the second category only if both the above checkboxes are having a value
<div class="category 2" *ngIf="someForm.controls.cb1.value && someForm.controls.cb2.value">
<mat-checkbox
formControlName="cb11"
[disabled]="!someForm.controls.cb1.value" // This will be disabled if the value is false which will make the condition true
>
Checkbox 11
</mat-checkbox>
<mat-checkbox
formControlName="cb12"
[checked]="someForm.controls.cb1.value" // It will be checked only if cb1 is checked
>
Checkbox 12
</mat-checkbox>
</div>
...
</form>
Du behöver inte alltid göra det från TS. Men om du vill göra det i TS, kommer du att skriva något mycket liknande:
this.someForm.controls.cb1.valueChanges.subscribe(data => {
if (data) {
this.someForm.controls.cb2.disable();
// After this you can remove the validators for the disabled field
this.someForm.controls.cb2.setValidators(null);
this.someForm.controls.cb2.updateValueAndValidity();
}
})
