Comment définir la valeur par défaut pour tous les champs de formulaire dans angular 2 formulaires réactifs?)
Voici le plnkr pour reproduire le problème
Le code ci-dessous ne met pas à jour les valeurs de liste déroulante car un objet lui est associé.
Remarque: Ici, je dois définir la valeur par défaut pour tous les champs de formulaire avec la réponse reçue de l'API Backend.
Composant.html
<form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm.value, myForm.valid)">
<div class="form-group">
<label>Country:</label>
<select formControlName="country">
<option *ngFor="let country of masterCountries" [ngValue]="country">{{country.countryName}}</option>
</select>
</div>
<div class="form-group">
<label for="">Name</label>
<input type="text" class="form-control" formControlName="name">
<small [hidden]="myForm.controls.name.valid || (myForm.controls.name.pristine && !submitted)" class="text-danger">
Name is required (minimum 5 characters).
</small>
<!--<pre class="margin-20">{{ myForm.controls.name.errors | json }}</pre>-->
</div>
<button type="submit" class="btn btn-default">Submit</button>
<div class="margin-20">
<div>myForm details:-</div>
<pre>Is myForm valid?: <br>{{myForm.valid | json}}</pre>
<pre>Is myForm submitted?: <br>{{submitted | json}}</pre>
<pre>myForm value: <br>{{myForm.value | json}}</pre>
</div>
Composant.ts
export class AppComponent implements OnInit {
public myForm: FormGroup;
public masterCountries: any[] = [{"countryCode":"AF","countryName":"Afghanistan"},{"countryCode":"AL","countryName":"Albania"},{"countryCode":"DZ","countryName":"Algeria"},{"countryCode":"AS","countryName":"American Samoa"},{"countryCode":"AD","countryName":"Andorra"}];
// Sample response received from backend api
public CountryResponse = {country: {"countryCode":"AF","countryName":"Afghanistan"}, name: 'test123'};
constructor(private _fb: FormBuilder) { }
ngOnInit() {
// the short way
this.myForm = this._fb.group({
country: [''],
name: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
});
(<FormGroup>this.myForm)
.setValue(this.CountryResponse, {onlySelf: true});
}
save(model: User, isValid: boolean) {
this.submitted = true;
console.log(model, isValid);
}
}
Faites-moi savoir s'il existe un autre moyen de définir la forme entière.
Il suffit de changer ceci:
(<FormGroup>this.myForm)
.setValue(this.CountryResponse, {onlySelf: true});
Dans ceci:
const selectedCountry = this.masterCountries.find(country => country.countryCode === this.CountryResponse.country.countryCode)
this.CountryResponse.country = selectedCountry;
(<FormGroup>this.myForm)
.setValue(this.CountryResponse, {onlySelf: true});
Comme dit précédemment, vous devez transmettre exactement la même référence de l'objet
Je sais que c’est une vieille question, mais si quelqu'un le cherche, il existe maintenant un meilleur moyen de définir une valeur dans l’ensemble du formulaire, avec PatchValue:
this.myForm.patchValue({
country: this.CountryResponse,
name: 'Any Name'
});
cela permet aussi de faire en sorte que vous puissiez toujours faire quelque chose comme:
this.myForm.patchValue({ country: this.CountryResponse });
ou vous pouvez définir la valeur dans un seul contrôle:
this.myForm.get('country').setValue(this.CountryResponse);
Votre code ne fonctionne pas car bien que votre this.selectedCountry
semble avoir les mêmes valeurs de champs que l’un des éléments de this.masterCountries
, ils sont pas le même objet. Qui fait select.value === option.value
La comparaison retourne toujours false
.
Pour que cela fonctionne, il suffit de changer votre fonction setValue
comme suit:
(<FormControl>this.form.controls['country'])
.setValue(this.masterCountries[0], { onlySelf: true });
Ou vous pouvez simplement le définir lors de la création du fichier FormGroup
:
this.myForm = this._fb.group({
country: [this.masterCountries[0]],
name: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
});
Lorsque vous déclarez le contrôle de formulaire ou initialisez, transmettez la valeur par défaut en tant que paramètre
MyFormControl: FormControl = new FormControl('Default value');