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?
formGroupName
por formGroup
todas partes podría solucionar el problema. Pero necesitará una forma de obtener la FormGroup
instancia correcta para cada grupo anidado.
oneOf
de un conjunto conocido de posibles entradas como name
,personal
, address
etc.
[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.