J'ai un composant partagé qui est une liste déroulante html et css. J'appelle ce composant partagé à partir d'un composant parent avec des données différentes.
Par exemple, j'ai 3 instances de composant partagé du composant parent, donc le groupe de formulaires parent aura 3 formControls. Étant donné que les 3 contrôles de formulaire sont désormais un composant partagé. Comment définir et obtenir des données sélectionnées dans les 3 listes déroulantes.
De même, si un élément par défaut doit être défini pour une liste déroulante, comment pouvons-nous y parvenir?
L'objectif principal ici est d'accéder / d'obtenir toutes les valeurs formControlName dans le groupe de formulaires du composant parent.
J'ai joint le code de démonstration https://stackblitz.com/edit/angular-mncdy5 S'il vous plaît, aidez-moi car je suis dans une phase d'apprentissage!
3 Réponses :
Vous devez implémenter ControlValueAccessors dans le composant partagé afin de pouvoir leur attacher formControls dans le composant parent. Voici un excellent article à ce sujet.
https://medium.com/@majdasab/implementing-control-value-accessor-in-angular-1b89f2f84ebf
Voici comment votre composant customDropdown doit se pencher pour implémenter ControlValueAccessors
this.parentForm = this.fb.group({ district: ['bangalore', Validators.required], <--- SETS THE DEFAULT VALUE OF THE FORM CONTROL distance: [''], state:[''] });
Maintenant que nous avons ajouté la possibilité d'attacher formControls à votre composant personnalisé, vous pouvez les ajouter au code HTML de votre app.component:
<form [formGroup]="parentForm"> <app-common-dropdown placeHolder="select district" [dropDownId]="'districtLabel'" [dataList]="['bangalore','chennai','pune']" formControlName="district" ></app-common-dropdown> <app-common-dropdown placeHolder="select distance" [dropDownId]="'distanceLabel'" [dataList]="[100,200,300,400]" formControlName="distance" ></app-common-dropdown> <app-common-dropdown placeHolder="select state" [dropDownId]="'stateLabel'" [dataList]="['karnataka','tamil nadu','mumbai']" formControlName="state" ></app-common-dropdown> </form> <button type="submit" (click)="getFormValues()">submit</button>
Et vous devrez ajuster les noms dans votre formGroup car ils ne correspondent pas au formulaire html
import { OnInit } from '@angular/core'; import { Component, forwardRef, HostBinding, Input } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-common-dropdown', templateUrl: './common-dropdown.component.html', styleUrls: ['./common-dropdown.component.css'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CommonDropdownComponent), multi: true } ] }) export class CommonDropdownComponent implements ControlValueAccessor { @Input() placeHolder: string; @Input() dropDownId: string; @Input() dataList: any; onChange: any = () => {} onTouch: any = () => {} val= "" // this is the updated value that the class accesses set value(val){ // this value is updated by programmatic changes if( val !== undefined && this.val !== val){ this.val = val this.onChange(val) this.onTouch(val) } constructor() { } ngOnInit() { } // this method sets the value programmatically writeValue(value: any){ this.value = value } registerOnChange(fn: any){ this.onChange = fn } registerOnTouched(fn){ this.onTouch = fn } propagateChange(_){ } selectClicked(event: any) { const ele = event.srcElement.parentNode; ele.classList.toggle('cs-active'); } selectedOption(ctrl: string, value: string) { this.onChange(value) // <-- CRUCIAL need to inform formControl to update the value document.getElementById(ctrl).innerHTML = value; const ele = document.getElementById(ctrl).parentElement; ele.classList.toggle('cs-active'); } closeDropDown(event: any) { const ele = event.srcElement; ele.classList.remove('cs-active'); } }
formControlName doit correspondre à une propriété dans le parentForm.
@Quellson pourriez-vous s'il vous plaît regarder dans mon code de démonstration et me dire quel est le bon endroit pour ajouter un formControlName dans mon composant partagé.
@Quellson, merci mon pote. L'implémentation ci-dessus donne simplement la bonne capacité de contrôler le groupe de formulaires à partir du composant parent lui-même
Heureux que cela ait aidé!
pourriez-vous s'il vous plaît laissez-moi savoir comment définir la valeur par défaut du composant parent. Je dois définir la valeur par défaut du district comme «bangalore». J'ai essayé d'utiliser this.parentForm.controls ['district']. SetValue ('bangalore') - cela ne fonctionne pas
J'ai mis à jour ma réponse pour que le district ait une valeur par défaut pour commencer, la définition des valeurs par défaut est effectuée lors de l'initialisation du formGroup.
J'ai essayé de répliquer avec votre entrée mais je n'ai pas pu le définir. Veuillez vérifier ce stackblitz.com/edit/angular-nuagbc . Merci de votre aide.
J'ai changé votre code de démonstration, vérifiez ici: https://stackblitz.com/edit/ angular-sge8r3
Dans CommonDropdownComponent
j'ai ajouté un Output ()
qui émet la valeur sélectionnée dans la liste déroulante:
setDistrict(value: string): void { this.district = value; }
merci, mais nous pourrions finir par ajouter une nouvelle méthode et une nouvelle variable à chaque fois que nous aurons une nouvelle liste déroulante. Et aussi il serait difficile de gérer les validations de cette manière.
@Onera vous pouvez également éviter de créer des variables et des méthodes pour chaque liste déroulante. Vous pouvez définir des valeurs dans parentForm
. Et il peut également y avoir une méthode pour cela, qui obtiendra un type de liste déroulante comme argument.
Un moyen de définir une valeur par défaut dans la liste déroulante?
Il existe plusieurs façons de procéder. @porgo mentionné est une méthode.
Veuillez vérifier l'url ci-dessous pour l'implémentation en utilisant @ViewChild
https://stackblitz.com/edit/angular-k92uxr
Veuillez vous référer à l'url ci-dessous pour les composants de communication b.w
https://angularfirebase.com/lessons/sharing-data -entre-composants-angulaires-quatre-méthodes /