Angular 7 和 angular material 如何获取 mat-select 的 selected 选项文本而不是它的值
Angular 7 and angular material how to get the selected option text of mat-select instead of its value
我需要获取 material 下拉列表 <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>
</div>
</td>
</ng-container>
这是我正在尝试做的事情:
@ViewChild('familyRelation') familyRel: ElementRef;
并更改下拉列表的选择:
onChange(data, i, type) {
let c = this.familyRel.nativeElement.innerText;
console.log(c)
}
我遇到了以下错误:
ERROR TypeError: Cannot read property 'innerText' of undefined
at
当我删除 innerText
时,安慰值是:
undefined
如您在 stackblitz 中所见,我需要什么,如果我选择 Parent
,我想将 Parent
放入变量而不是 1
它的 id
.
请注意,(selectionChange)=onChange(element,...)
中的element
、i
、hh
后面函数中会用到,先不提了。
使用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.
更新了代码,并在 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>
您可以使用 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
很抱歉来晚了。我真的很害怕阅读上面的所有答案...
该解决方案比任何建议的答案都简单直接,因为 select 组件只是将 selected 模型作为 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>
不需要每个垫子选项的(单击)处理程序,因为这不是必需的,如果您有很多选项,可能会导致性能问题。现在,在控制器上:
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';
虽然晚了点,但是回答给了我一点启发,这里有个思路:
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作为value的,所以如果要匹配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>
你可以使用这个方法。
<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>
Component.ts
@ViewChild('jobMatSelect') private jobMatSelected: MatSelect;
this.jobSelected = this.jobMatSelected.triggerValue;
我需要获取 material 下拉列表 <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>
</div>
</td>
</ng-container>
这是我正在尝试做的事情:
@ViewChild('familyRelation') familyRel: ElementRef;
并更改下拉列表的选择:
onChange(data, i, type) {
let c = this.familyRel.nativeElement.innerText;
console.log(c)
}
我遇到了以下错误:
ERROR TypeError: Cannot read property 'innerText' of undefined at
当我删除 innerText
时,安慰值是:
undefined
如您在 stackblitz 中所见,我需要什么,如果我选择 Parent
,我想将 Parent
放入变量而不是 1
它的 id
.
请注意,(selectionChange)=onChange(element,...)
中的element
、i
、hh
后面函数中会用到,先不提了。
使用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.
更新了代码,并在 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>
您可以使用 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
很抱歉来晚了。我真的很害怕阅读上面的所有答案...
该解决方案比任何建议的答案都简单直接,因为 select 组件只是将 selected 模型作为 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>
不需要每个垫子选项的(单击)处理程序,因为这不是必需的,如果您有很多选项,可能会导致性能问题。现在,在控制器上:
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';
虽然晚了点,但是回答给了我一点启发,这里有个思路:
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作为value的,所以如果要匹配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>
你可以使用这个方法。
<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>
Component.ts
@ViewChild('jobMatSelect') private jobMatSelected: MatSelect;
this.jobSelected = this.jobMatSelected.triggerValue;