【问题标题】:Angular 7 and angular material how to get the selected option text of mat-select instead of its valueAngular 7和角度材料如何获取mat-select的选定选项文本而不是其值
【发布时间】:2019-05-08 05:45:20
【问题描述】:

我需要获取材料下拉列表<mat-select>的选定文本而不是它的值:

<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>

这就是我想要做的:

@ViewChild('familyRelation') familyRel: ElementRef;

并且在更改下拉列表的选择时:

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

我遇到了以下错误:

错误类型错误:无法读取未定义的属性“innerText” 在

当我删除 innerText 时,控制台值为:

未定义

正如您在stackblitz 中看到的那样,我需要什么,如果我选择了Parent,我想将Parent 放入一个变量而不是1,它是它的id

请注意,(selectionChange)=onChange(element,...) 中的elementihh 在函数后面会用到,所以现在就忘了吧。

【问题讨论】:

    标签: angular angular-material angular-reactive-forms angular7


    【解决方案1】:

    很抱歉迟到了。我真的很害怕阅读上面的所有答案......

    该解决方案比任何建议的答案都更容易和直接,因为选择组件只是将所选模型作为selectionChange 参数的一部分传递。

    但首先,对您的示例进行一些更正。你已经声明了一个接口,所以使用它:

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

    所以,在你的构造函数中:

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

    而不是您在 StackBlitz 中放入的内容...然后您的视图将变为:

    <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>
    

    每个 mat-option 都不需要 (click) 处理程序,因为它不是必需的,如果您有很多选项,可能会导致性能问题。现在,在控制器上:

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

    或者,如果您愿意,也可以使用类型化变体:

    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);
    }
    

    但不要忘记导入...

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

    【讨论】:

    • 这应该是公认的答案。包括打字,也是我见过的很多答案中最简单的答案。一个小的改进,您可以将导入语句简化为 1:import {MatSelectChange, MatOption} from '@angular/material';
    【解决方案2】:

    您可以使用 mat-option 为循环添加索引,然后将其传递给 onChange() 方法,它将允许您从数组中获取选定的元素。

    <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);
    }
    

    这里有更新代码:link

    【讨论】:

    • 成功了。这是一个长期的解决方案还是只是暂时的?
    • 它工作但检查链接,当getData() 被触发时它正在读取以前的值:stackblitz.com/edit/angular-material-wuavbe
    • 据我在您的示例中看到,mat-option 索引在 mat-select 级别上无法访问。
    【解决方案3】:

    更新了代码,在options上添加了click事件

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

    增加了一项功能

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

    在视图中添加了点击事件

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

    【讨论】:

    • 你确定吗?即使在 stackblitz 上,它也给了我 innerText does not exists 错误
    • 你检查过这个链接https://stackblitz.com/edit/angular-material-w89kwc?embed=1&amp;file=app/app.component.ts
    • 看看发生了什么。这个下拉列表是一个表单控件数组。当我更改选定的选项时,它给了我旧的选定选项。
    • 如果我检查链接并更改值,我会在我选择的控制台中获得准确的值
    • 您必须检查 jkubm 答案。这两个问题都存在于该链接中
    【解决方案4】:

    使用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 监听 'change' 事件,因为 Firefox 中的选择不会触发 'input' 事件。 DOC.

    【讨论】:

      【解决方案5】:

      虽然有点晚了,但答案给了我一点启发,这里有一个想法:

      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>
      

      这种方法的缺点是不能使用formControlName,因为mat-option使用index作为值,所以如果要匹配formgroup,可以改成这样:

      // 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>
      

      【讨论】:

        【解决方案6】:

        你可以使用这个方法。

        <mat-select [(ngModel)]="job" #jobMatSelect placeholder="-Select Job-" class="form-control" required>
         <mat-option *ngFor="let item of Jobs" [value]="item.jobId" [disabled]="item.status == false" [ngClass]="{'col-red':item.status == false}"> ({{item.viewValue}})</mat-option>
         </mat-select>
        

        组件.ts

         @ViewChild('jobMatSelect') private jobMatSelected: MatSelect;
         this.jobSelected = this.jobMatSelected.triggerValue;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-06-17
          • 2018-08-28
          • 1970-01-01
          • 1970-01-01
          • 2022-10-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多