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?
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.