Aquí está mi problema.
Tengo un JSON dinámico que necesito convertir a un formulario. Entonces, utilicé formas reactivas y al revisar todas las propiedades del JSON creo un FormGroup o FormControl, de esta manera:
sampleJson ={prop1:"value1", prop2: "value2",...}
...
myForm: FormGroup;
myKeys=[];
...
ngOnInit() {
this.myForm = this.getFormGroupControls(this.sampleJson, this.myKeys);
}
getFormGroupControls(json:any,keys): FormGroup{
let controls = {};
let value = {};
for (let key in json) {
if (json.hasOwnProperty(key)) {
value = json[key];
if (value instanceof Object && value.constructor === Object) {
keys.push({"key":key,children:[]});
controls[key] = this.getFormGroupControls(value,keys[keys.length-1].children);
} else {
keys.push({"key":key,children:[]});
controls[key] = new FormControl(value);
}
}
}
return new FormGroup(controls);
}
Después de hacerlo, uso plantillas recursivas para construir el formulario, si no uso plantillas recursivas, hago que el formulario funcione. Sin embargo, con las plantillas recursivas obtengo errores:
<form [formGroup]="myForm">
<div class="form-group">
<ng-template #nodeTemplateRef let-node>
<div class="node">
<div *ngIf="node.children.length">
{{"section [formGroupName]="}} {{ getNodeKey(node) }}
<section style="display:block;margin:20px;border:solid 1px blue;padding-bottom: 5px;"
[formGroupName]="getNodeKey(node)" >
<h1>{{ node.key }}</h1>
<ng-template
ngFor
[ngForOf]="node.children"
[ngForTemplate]="nodeTemplateRef">
</ng-template>
</section>
{{"end of section"}}
</div>
<div *ngIf="!node.children.length">
<label [for]="node.key">{{node.key}}</label>
<input type="text" [id]="node.key"
class="form-control">
</div>
</div>
</ng-template>
<ng-template *ngFor="let myKey of myKeys"
[ngTemplateOutlet]="nodeTemplateRef"
[ngTemplateOutletContext]="{ $implicit: myKey }">
</ng-template>
</div>
FormerComponent.html: 25 ERROR Error: no se puede encontrar el control con el nombre: 'carretera'
Eso corresponde a esta muestra JSON:
"address": {
"town": "townington",
"county": "Shireshire",
"road": {
"number": "1",
"street": "the street"
}
Se está mostrando, así que sé que los elementos están ahí. ¿Qué me estoy perdiendo?
angular
angular-reactive-forms
Dalorzo
fuente
fuente
[formGroupName]="road"
no es consciente de que está anidado bajo el grupo deaddress
formularios. Está buscando un grupo de formularios nombradoroad
directamente debajo de la raíz[formGroup]="myForm"
. Si anida un grupo deroad
formularios directamente debajomyForm
, verá que el error ya no aparece.formGroupName
porformGroup
todas partes podría solucionar el problema. Pero necesitará una forma de obtener laFormGroup
instancia correcta para cada grupo anidado.oneOf
de un conjunto conocido de posibles entradas comoname
,personal
,address
etc.Respuestas:
O si aún desea la jerarquía de grupos / controles de formulario, puede usar las directivas formGroup y formControl pasándolas de forma recursiva (en lugar de formGroupName y formControlName)
Enlace Stackblits
NB: el mismo problema aquí: Recursive ReactiveForm no puede encontrar formGroups dentro de la plantilla
fuente
El problema con su código actual parece ser que ng-template parent es el componente de su aplicación, por lo que no tiene en cuenta otros formGroupNames en las plantillas principales que definió y siempre busca en el FormGroup raíz.
También parece que el nombre completo del grupo / nombre de control no es compatible con las plantillas (por ejemplo, no se puede usar
formGroupName="address.road"
)Si necesita por alguna razón formGroups, puede pasarlos en contexto a las plantillas. O puede dirigirse a formControls directamente:
formGroupName
de la plantillakeys.push({"key":key,children:[], fullKey: parent ? parent.fullKey + '.' + key: key});
(también puede almacenar laFormControl
instancia en sí).<input type="text" [formControl]="myForm.get(node.fullKey)"
Ejemplo de Stackblitz
fuente