Une autre approche consiste à améliorer la directive "enabled" de ce système. réponse de stackoverflow
Nous allons améliorer la directive pour permettre de désactiver non seulement le contrôle mais aussi tous les contrôles d'un formulaire.
@Directive({
selector: '[disableControl]'
})
export class DisableControlDirective {
@Input() set disableControl(condition: boolean) {
if (this.ngControl) { //if is an ngControl
if (condition)
this.ngControl.control.disable();
else
this.ngControl.control.enable();
}
if (this.controls) { //if is a formGroup, we ask about the inners controls
this.controls.forEach((x: any) => {
let control:boolean=false;
if (this.innerControl) //we check if the control has
//his own DisableControlDirective
control=(this.innerControl.find(inner=>x==inner.ngControl)!=null)
if (!control) { //if it has not a own DisabledControlDirective
if (condition)
x.control.disable();
else
x.control.enable()
}
})
}
}
@ContentChildren(NgControl) controls: QueryList<NgControl>
@ContentChildren(DisableControlDirective)
innerControl:QueryList<DisableControlDirective>
//see that make public ngControl to use when check if a innerControl has
//the directive
constructor(@Optional() public ngControl: NgControl) {}
}
Si nous appliquons la directive à un fromGroup, tous les contrôles inners sont désactivés/activés. Pour obtenir le contrôle interne, nous utilisons @ContentChildren(NgControl)
. Lorsque nous injectons le NgControl, nous devons mettre @Optional()
parce que dans un FormGroup nous n'avons PAS de NgControl - rappelez-vous que NgControl est tout ce qui a la directive [formControlName], [NgModel] ou [formControl].
Nous devons vérifier si nos contrôles internes n'ont pas de directive [disableControl]. Dans ce cas, nous devons sauter ce contrôle. Pour cela, nous devons récupérer ces contrôles en utilisant @ContentChildren(DisableControlDirective)
et le vérifier.
Notre forme devient très "facile", mais nous passons comme @Input
le mode d'édition à l'enfant
<form [formGroup]="parentForm" [disableControl]="!editMode" (ngSubmit)="onSave()">
<input formControlName="id">
<input formControlName="name">
<app-child-component [editMode]="editMode"></app-child-component>
</form>
//and our children component
<form [formGroup]="identifyForm" [disableControl]="!editMode">
<input type="radio" name="identity" value="yes" formControlName="identity"> Yes
<input type="radio" name="identity" value="no" formControlName="identity" > No
<input formControlName="identityname"
[disableControl]="!editMode || identifyForm.get('identity').value=='no'">
</form>
Nous pouvons voir le résultat final dans ce stackblitz