Aqui está o meu problema.
Eu tenho um JSON dinâmico que preciso converter em um formulário. Então, usei formulários reativos e, passando por todas as propriedades do JSON, crio um FormGroup ou FormControl, desta maneira:
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);
}
Depois de fazer isso, uso modelos recursivos para criar o formulário; se não usar modelos recursivos, faço o formulário funcionar. No entanto, com modelos recursivos, estou recebendo erros:
<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 ERRO Erro: Não é possível encontrar o controle com o nome: 'road'
Isso corresponde a este exemplo JSON:
"address": {
"town": "townington",
"county": "Shireshire",
"road": {
"number": "1",
"street": "the street"
}
Eu tenho está sendo exibido, então eu sei que os elementos estão lá. o que estou perdendo?
angular
angular-reactive-forms
Dalorzo
fonte
fonte
[formGroupName]="road"
não está ciente de que está aninhado no grupo deaddress
formulários. Ele está procurando um grupo de formulários chamadoroad
diretamente sob a raiz[formGroup]="myForm"
. Se você aninhar um grupo deroad
formulários diretamente abaixomyForm
, verá que o erro não aparece mais.formGroupName
porformGroup
qualquer lugar pode corrigir o problema. Mas você precisará de uma maneira de capturar aFormGroup
instância correta para cada grupo aninhado.oneOf
de um conjunto conhecido de possíveis entradas comoname
,personal
,address
etcRespostas:
Ou se você ainda deseja hierarquia de grupos / controles de formulário, pode usar as diretivas formGroup e formControl passando-as recursivamente (em vez de formGroupName e formControlName)
Link Stackblits
NB: mesmo problema aqui: Recursive ReactiveForm não pode encontrar formGroups dentro do modelo
fonte
O problema com o código atual parece ser que o pai do modelo ng é o componente do aplicativo, portanto, ele não leva em conta outros formGroupNames nos principais modelos que você definiu e sempre procura no FormGroup raiz.
Parece também que o nome completo do grupo / nome do controle não é suportado nos modelos (por exemplo, não é possível usar
formGroupName="address.road"
)Se você precisar, por algum motivo, de formGroups - poderá passá-los em contexto para modelos. Ou você pode endereçar formControls diretamente:
formGroupName
do modelokeys.push({"key":key,children:[], fullKey: parent ? parent.fullKey + '.' + key: key});
(você pode armazenar aFormControl
própria instância também ofc.)<input type="text" [formControl]="myForm.get(node.fullKey)"
Exemplo Stackblitz
fonte