J'ai le html suivant dans mon composant, j'essaie de générer un formulaire dynamiquement en fonction du nombre d'éléments sélectionnés qui peuvent être de 0 à N
[ { auth-system: "c" ,auth-user: "d" ,auth-user-id: "e" ,email: "h" ,module: "g" ,rpm: "b" ,task-client-key: "f" ,users: "a" }, { auth-system: "k" ,auth-user: "l" ,auth-user-id: "m" ,rpm: "j" ,task-client-key: "n" ,users: "i" } ]
lorsque je crée de nouveaux éléments et que je soumets le formulaire que j'obtiens en conséquence sur form.value quelque chose comme ceci:
0-auth-system: "c" 0-auth-user: "d" 0-auth-user-id: "e" 0-email: "h" 0-module: "g" 0-rpm: "b" 0-task-client-key: "f" 0-users: "a" 1-auth-system: "k" 1-auth-user: "l" 1-auth-user-id: "m" 1-rpm: "j" 1-task-client-key: "n" 1-users: "i"
et ce que je veux en fait, c'est une sortie comme la suivante car il est plus facile à traiter et je ne veux pas développer de code pour analyser la structure précédente si je peux l'avoir sous forme de tableau:
<form #form="ngForm" id="formGroupExampleInput"> <div class="col-xs-5 col-md-offset-1"> <a class="list-group-item clearfix" *ngFor="let selectedApi of selectedApps;let i=index"> <div class="pull-right"> <button type="button" class="close" (click)="removeFromSelectedApi(i)"> <span aria-hidden="true">×</span> </button> </div> <div class="pull-left"> <h4 class="list-group-item-heading">{{selectedApi.url}}</h4> <p class="list-group-item-text">{{selectedApi.method}}</p> <div class="form-group"> <input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-users" placeholder="number of users" ngModel> <input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-rpm" placeholder="request per minute between all users" ngModel> </div> <hr> <div class="form-group" *ngFor="let requiredHeader of selectedApi.requiredHeaders; let in=index"> <input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-{{requiredHeader}}" placeholder={{requiredHeader}} ngModel> </div> <div class="form-group" *ngFor="let requiredParameter of selectedApi.requiredParametersInURL; let in=index"> <input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-{{requiredParameter}}" placeholder={{requiredParameter}} ngModel> </div> <div class="form-group" *ngIf="selectedApi.method=='POST' || selectedApi.method=='PUT' || selectedApi.method=='DELETE'"> <!-- <textarea class="form-control" id="formGroupExampleInput" name="{{i}}-{{requiredHeader}}" rows=20></textarea> --> <textarea class="form-control" rows="5" name="{{i}}-body" id="{{i}}-body" placeholder="body" ngModel></textarea> </div> </div> </a> </div> <div class="pull-right"> <button class="btn btn-success btn-lg" (click)="onSubmitTest(form)">Submit</button> </div> </form>
Quelqu'un sait comment je peux y parvenir?
4 Réponses :
J'avais un problème similaire.
Je suis sûr que cela vous donnera une idée si vous le lisez attentivement
Bien que le partage d'un lien puisse être utile, ce n'est pas une réponse. Les réponses doivent contenir une explication au lieu de liens purs ou de code
correct mais si le lien est suivi il fournira une réponse, le lien dirige vers un tutoriel qui explique en détail. À quoi ça sert de l'expliquer si le lien le fait déjà? La répétition n'est pas nécessaire
myFormUnit: FormGroup; protected onInitializeComponent() { this.myFormUnit = this.fb.group({ items: this.fb.array([]) }); } private fillUnitform(input?: any) { this.myFormUnit = this.fb.group({ items: this.fb.array( [] // [this.buildItem(null, 'lesson'), this.buildItem(null, 'lesson')] ) }); this.gradeListItems.forEach(item => { if (item.value !== "12") { const tmp: Array<any> = this.gridData.data; tmp.forEach(element => { if (element.lesson_type === item.value) { item.value = element.num_unit; } }); const fbb = this.myFormUnit.get("items") as FormArray; if (item.value !== "12") { const newItem = { name: item.text, grade_list: item.value, min_grade: item.min_grade, max_grade: item.max_grade }; if (input) { // if (input.length > 0) input.forEach((element: any) => { if (element.grade_list === item.value) { newItem.min_grade = element.min_grade; newItem.max_grade = element.max_grade; } }); } fbb.push(this.fb.group(this.buildItem(newItem))); } } }); } buildItem(item: any) { return { name: new FormControl(item.name), grade_list: new FormControl(item.grade_list), min_grade: new FormControl(item.min_grade), max_grade: new FormControl(item.max_grade) }; } submit(){ this.myFormUnit.value.items.forEach( (item): any => { if (item.min_grade || item.max_grade) { grade_list.push({ grade_list: item.grade_list, min_grade: item.min_grade, max_grade: item.max_grade }); } } ); }
mosi98, vous n'avez pas besoin de créer un formGroup avec un formArray, vous pouvez utiliser un formArray directement -voir ma réponse-
@ mosi98, vous n'avez pas besoin de créer un formGroup avec des éléments de propriété, et "items" était un formArray
@Component({ selector: 'my-app', template:` <!--see that, form is a FormArray, but we use [formGroup] too--> <form [formGroup]="form"> <div *ngFor="let group of form.controls;let i=index"> <div [formGroup]="group"> <input formControlName="name"/> <input formControlName="grade_list"/> </div> </div> </form> <hr/> <pre> {{form?.value|json}} </pre> `, styleUrls: [ './app.component.css' ] }) export class AppComponent { name = 'Angular'; items=[ {name: "c",grade_list: "d",min_grade: "e",max_grade: "h"}, {name: "c",grade_list: "d",min_grade: "e",max_grade: "h"}, {name: "c",grade_list: "d",min_grade: "e",max_grade: "h"}] form:FormArray=new FormArray(this.buildForm(this.items)) //return an array of FormGroup buildForm(items:any[]):FormGroup[] { return items.map(x=>this.buildItem(x)) } //return a formGroup buildItem(item: any):FormGroup { return new FormGroup({ name: new FormControl(item.name), grade_list: new FormControl(item.grade_list), min_grade: new FormControl(item.min_grade), max_grade: new FormControl(item.max_grade) }); } }
les éléments du tableau sont dynamiques, ils peuvent être de 1 à n <100, donc je ne peux pas créer une classe comme celle pour les éléments
MBG, les "éléments" dans mon exemple sont un "moyen facile" de donner des valeurs. Dans le "monde réel", je suppose que les données proviennent d'un service. Dans l'abonnement du service, vous pouvez appeler this.buildForm en utilisant le tableau d'objets que vous recevez. La seule chose que je veux faire remarquer est que si vous avez un tableau d'objets, vous pouvez gérer le FormArray lui-même
vous pouvez déclarer les noms d'entrée sous forme de tableau comme ceci:
<!-- ... --> <div *ngFor="let selectedApi of selectedApps;let i=index"> <input type="text" [attr.name]="'obj['+i+'][users]'"> <input type="text" [attr.name]="'obj['+i+'][module]'"> <input type="text" [attr.name]="'obj['+i+'][email]'"> </div> <!-- ... -->
Vous obtenez donc un tableau d'objets.