6 votes

Angular 7 et angular material comment obtenir le texte de l'option sélectionnée de mat-select au lieu de sa valeur

J'ai besoin d'obtenir le texte sélectionné dans une liste déroulante de matériaux. <mat-select> au lieu de sa valeur :

<ng-container matColumnDef="fr">
        <th mat-header-cell *matHeaderCellDef> Family Rel. </th>
        <td mat-cell *matCellDef="let element; let i = index;">
          <div [formGroupName]="i">
            <mat-form-field color="warn" appearance="outline">
              <mat-label>Family Relation</mat-label>
              <mat-select #familyRelation (selectionChange)="onChange(element, i, 'hh')" id="family_relation"
                formControlName="fr" placeholder="Family Relation">
                <mat-option *ngFor="let familyRelation of familyRelationArray;" [value]="familyRelation.family_relation_id">
                  {{familyRelation.family_relation_type}}
                </mat-option>
              </mat-select>
            </mat-form-field>&nbsp;
          </div>
        </td>
      </ng-container>

Et voici ce que j'essaie de faire :

@ViewChild('familyRelation') familyRel: ElementRef;

Et sur le changement de sélection de la liste déroulante :

onChange(data, i, type) {
    let c = this.familyRel.nativeElement.innerText;
    console.log(c)
}

J'ai eu l'erreur suivante :

ERROR TypeError : Impossible de lire la propriété 'innerText' d'undefined à l'adresse

Et quand je retire innerText la valeur consolée est :

indéfini

Ce dont j'ai besoin, comme vous pouvez le voir dans le stackblitz si j'ai choisi Parent Je veux obtenir Parent dans une variable et non 1 qui est son id .

Veuillez noter que element , i y hh en (selectionChange)=onChange(element,...) sont utilisés plus tard dans la fonction, alors oubliez-les maintenant.

13voto

Vi100 Points 2188

Désolé d'être en retard à la fête. Je suis vraiment horrifié de lire toutes les réponses ci-dessus...

La solution est beaucoup plus simple et directe que toutes les réponses proposées, car le composant select transmet simplement le modèle sélectionné dans le cadre de la fonction selectionChange argument.

Mais d'abord, quelques corrections à votre exemple. Vous avez déclaré une interface, alors UTILISEZ-LE :

export interface FamilyRelation {
    id: number;
    type: string;
}

Donc, dans votre constructeur :

 constructor() {
    this.familyRelationArray=[
    {
      id: 1,
      type: 'Parent'
    },
    {
      id: 2,
      type: 'Sister'
    }
  ]
}

et non ce que vous mettez dans votre StackBlitz... Alors votre vue deviendra ceci :

<mat-select (selectionChange)="onChange($event)" id="family_relation" placeholder="Family Relation">
    <mat-option *ngFor="let familyRelation of familyRelationArray;" [value]="familyRelation.id">
        {{familyRelation.type}}
    </mat-option>
</mat-select>

Il n'est pas nécessaire d'avoir un gestionnaire (click) pour chaque option du tapis, car cela n'est pas nécessaire et pourrait entraîner des problèmes de performance si vous avez beaucoup d'options. Maintenant, sur le contrôleur :

onChange(ev: any) {
   let optionText = ev.source.selected.viewValue;
   console.log(optionText);
}

ou, si vous préférez, la variante typée :

onChange(ev: MatSelectChange) {
   let optionText = (ev.source.selected as MatOption).viewValue;  //use .value if you want to get the key of Option
   console.log(optionText);
}

mais n'oubliez pas les importations...

import { MatSelectChange } from '@angular/material/select';
import { MatOption } from '@angular/material/core';

4voto

jakubm Points 352

Vous pouvez ajouter l'index à la boucle avec mat-option puis le passer à la méthode onChange() et cela vous permettra de récupérer l'élément sélectionné dans le tableau.

<mat-select #familyRelation (selectionChange)="onChange($event.value, element, i, 'hh')" id="family_relation" placeholder="Family Relation">
    <mat-option *ngFor="let familyRelation of familyRelationArray; let i=index" [value]="i">
        {{familyRelation.family_relation_type}}
    </mat-option>
</mat-select>

 onChange(index, data, i, type) {
    console.log(this.familyRelationArray[index].family_relation_type);
}

Ici vous avez le code de mise à jour : enlace

3voto

Rohit.007 Points 2074

Mis à jour le code, et ajouté click sur l'événement options

https://stackblitz.com/edit/angular-material-w89kwc?embed=1&file=app/app.component.ts

Ajout d'une fonction

  getInnerText(innerText){
    console.log(innerText)
  }

Ajout d'un événement de clic dans la vue

<mat-option *ngFor="let familyRelation of familyRelationArray;" [value]="familyRelation.family_relation_id" (click)="getInnerText(familyRelation.family_relation_type)">
    {{familyRelation.family_relation_type}}
</mat-option>

2voto

Sachila Ranawaka Points 17611

Utilisez le compareWith

 <mat-select #familyRelation [compareWith]="compareFn" id="family_relation"  formControlName="fr" placeholder="Family Relation">
      <mat-option *ngFor="let familyRelation of familyRelationArray;" [value]="familyRelation.family_relation_id">
          {{familyRelation.family_relation_type}}
     </mat-option>
 </mat-select>

compareFn(data1 , data2){

}

compareWith écouter l'événement "change" parce que les événements "input" ne sont pas déclenchés pour les sélections dans Firefox. DOC .

1voto

Pork Jackson Points 103

Bien que ce soit un peu tard, mais les réponses m'ont un peu inspiré, voici une idée :

export interface IFamilyGroup{
    id: number;
    name: string;
    address: string;
}

familyGroup: IFamilyGroup[];

getSelectOption( family: IFamilyGroup ): void {
    console.log(family);
}

<mat-select (selectionChange)="getSelectOption( familyGroup[$event.value] )">
  <mat-option>none</mat-option>
  <mat-option
    *ngFor="let family of familyGroup; let i = index"
    value="{{i}}">
        {{ family.name }}
    </mat-option>
</mat-select>

L'inconvénient de cette méthode est que vous ne pouvez pas utiliser formControlName, car mat-option utilise l'index comme valeur, donc si vous voulez faire correspondre formgroup, vous pouvez le changer en ceci :

// this is formgroup data model
export interface IFamilyGroup{
    id: number;
    name: string;
    address: string;
}

export interface IFormGroupDataForm{
    family: FormControl;
    whatever1?: FormControl;
    whatever2?: FormControl;
}

dataForm: FormGroup;
family = new FormControl();

familyGroup: IFamilyGroup[];

constructor(
    private formBuilder: FormBuilder
  ) { }

ngOnInit(): void {
    this.initFormGroup();
}

private initFormGroup() {
    dataForm = this.fromFormGroupModel({
      family: this.family
      // any you need...
    });
}

private fromFormGroupModel( model: IFormGroupDataForm ): FormGroup {
    return this.formBuilder.group(model);
}

getSelectOption( family: IFamilyGroup ): void {
    this.family.setValue(family); // set family data object be value
}

<div [formGroup]="dataForm">
    <mat-select (selectionChange)="getSelectOption( familyGroup[$event.value] )">
      <mat-option>none</mat-option>
      <mat-option
        *ngFor="let family of familyGroup; let i = index"
        value="{{i}}">
            {{ family.name }}
        </mat-option>
    </mat-select>

    //...
</div>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X