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?
formGroupNamepor formGrouptodas partes podría solucionar el problema. Pero necesitará una forma de obtener la FormGroupinstancia correcta para cada grupo anidado.
oneOfde un conjunto conocido de posibles entradas como name,personal , addressetc.
[formGroupName]="road"no es consciente de que está anidado bajo el grupo deaddressformularios. Está buscando un grupo de formularios nombradoroaddirectamente debajo de la raíz[formGroup]="myForm". Si anida un grupo deroadformularios directamente debajomyForm, verá que el error ya no aparece.