![](/img/trans.png)
[英]Angular Material Select (mat-select) - How to set default value
[英]Angular Material: mat-select not selecting default
我有一个 mat-select,其中选项是数组中定义的所有对象。 我正在尝试将值设置为默认值之一,但是在页面呈现时它被选中。
我的 typescript 文件包含:
public options2 = [
{"id": 1, "name": "a"},
{"id": 2, "name": "b"}
]
public selected2 = this.options2[1].id;
我的 HTML 文件包含:
<div>
<mat-select
[(value)]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
我尝试将selected2
和mat-option
中的value
设置为 object 及其 id,并尝试在mat-select
中同时使用[(value)]
和[(ngModel)]
,但均无效。
我正在使用材料版本 2.0.0-beta.10
对模板中的值使用绑定。
value="{{ option.id }}"
应该是
[value]="option.id"
并在您选择的值中使用ngModel
而不是value
。
<mat-select [(value)]="selected2">
应该是
<mat-select [(ngModel)]="selected2">
完整代码:
<div>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</div>
从 版本 2.0.0-beta.12 开始,材质选择现在接受mat-form-field
元素作为父元素,因此它与其他材质输入控件一致。 升级后将div
元素替换为mat-form-field
元素。
<mat-form-field>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</mat-form-field>
使用compareWith
函数将选项值与选定值进行比较。 见这里: https : //material.angular.io/components/select/api#MatSelect
对于具有以下结构的对象:
listOfObjs = [{ name: 'john', id: '1'}, { name: 'jimmy', id: '2'},...]
像这样定义标记:
<mat-form-field>
<mat-select
[compareWith]="compareObjects"
[(ngModel)]="obj">
<mat-option *ngFor="let obj of listOfObjs" [value]="obj">
{{ obj.name }}
</mat-option>
</mat-select>
</mat-form-field>
并像这样定义比较函数:
compareObjects(o1: any, o2: any): boolean {
return o1.name === o2.name && o1.id === o2.id;
}
我正在使用 Angular 5 和带有 mat-select 的反应式形式,但无法获得上述任何一种解决方案来显示初始值。
我必须添加 [compareWith] 来处理 mat-select 组件中使用的不同类型。 在内部,似乎 mat-select 使用一个数组来保存选定的值。 如果打开该模式,这可能允许相同的代码处理多个选择。
这是我的解决方案:
Form Builder 来初始化表单控件:
this.formGroup = this.fb.group({
country: new FormControl([ this.myRecord.country.id ] ),
...
});
然后在你的组件上实现 compareWith 函数:
compareIds(id1: any, id2: any): boolean {
const a1 = determineId(id1);
const a2 = determineId(id2);
return a1 === a2;
}
接下来创建并导出确定 ID 函数(我必须创建一个独立的函数,以便 mat-select 可以使用它):
export function determineId(id: any): string {
if (id.constructor.name === 'array' && id.length > 0) {
return '' + id[0];
}
return '' + id;
}
最后将 compareWith 属性添加到您的 mat-select 中:
<mat-form-field hintLabel="select one">
<mat-select placeholder="Country" formControlName="country"
[compareWith]="compareIds">
<mat-option>None</mat-option>
<mat-option *ngFor="let country of countries" [value]="country.id">
{{ country.name }}
</mat-option>
</mat-select>
</mat-form-field>
您应该在mat-option
中将其绑定为[value]
,如下所示,
<mat-select placeholder="Panel color" [(value)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">
{{ option.name }}
</mat-option>
</mat-select>
您可以简单地实现自己的比较功能
[compareWith]="compareItems"
也请参阅文档。 所以完整的代码看起来像:
<div>
<mat-select
[(value)]="selected2" [compareWith]="compareItems">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
并在打字稿文件中:
compareItems(i1, i2) {
return i1 && i2 && i1.id===i2.id;
}
正如在 Angular 6 中已经提到的,在反应形式中使用 ngModel 已被弃用(并在 Angular 7 中删除),所以我修改了模板和组件如下。
模板:
<mat-form-field>
<mat-select [formControl]="filter" multiple
[compareWith]="compareFn">
<mat-option *ngFor="let v of values" [value]="v">{{v.label}}</mat-option>
</mat-select>
</mat-form-field>
组件的主要部分(省略了onChanges
等细节):
interface SelectItem {
label: string;
value: any;
}
export class FilterComponent implements OnInit {
filter = new FormControl();
@Input
selected: SelectItem[] = [];
@Input()
values: SelectItem[] = [];
constructor() { }
ngOnInit() {
this.filter.setValue(this.selected);
}
compareFn(v1: SelectItem, v2: SelectItem): boolean {
return compareFn(v1, v2);
}
}
function compareFn(v1: SelectItem, v2: SelectItem): boolean {
return v1 && v2 ? v1.value === v2.value : v1 === v2;
}
注意this.filter.setValue(this.selected) ngOnInit
以上。
它似乎适用于 Angular 6。
我就像在这些例子中那样做。 试图将 mat-select 的值设置为 mat-options 之一的值。 但是失败了。
我的错误是对数字类型变量执行 [(value)]="someNumberVariable" 而 mat-options 中的变量是字符串。 即使它们在模板中看起来相同,它也不会选择该选项。
一旦我将 someNumberVariable 解析为字符串,一切就完全没问题了。
因此,您似乎需要让 mat-select 和 mat-option 值不仅是相同的数字(如果您要显示数字),还要让它们是字符串类型。
我的解决方案是:
<mat-form-field>
<mat-select #monedaSelect formControlName="monedaDebito" [attr.disabled]="isLoading" [placeholder]="monedaLabel | async ">
<mat-option *ngFor="let moneda of monedasList" [value]="moneda.id">{{moneda.detalle}}</mat-option>
</mat-select>
TS:
@ViewChild('monedaSelect') public monedaSelect: MatSelect;
this.genericService.getOpciones().subscribe(res => {
this.monedasList = res;
this.monedaSelect._onChange(res[0].id);
});
使用对象:{id: number, detalle: string}
试试这个!
this.selectedObjectList = [{id:1}, {id:2}, {id:3}]
this.allObjectList = [{id:1}, {id:2}, {id:3}, {id:4}, {id:5}]
let newList = this.allObjectList.filter(e => this.selectedObjectList.find(a => e.id == a.id))
this.selectedObjectList = newList
我的解决方案有点棘手和简单。
<div>
<mat-select
[placeholder]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
我只是使用了占位符。 材质占位符的默认颜色为light gray
。 为了使它看起来像选择了该选项,我只是按如下方式操作 CSS:
::ng-deep .mat-select-placeholder {
color: black;
}
结合或默认值的设置仅在MatSelect属性的值相当于绑定到MatOption价值属性。 如果您将项目的caption
绑定到mat-option元素的value属性,您也必须将mat-select上的默认元素设置为项目的caption
。 如果您将项目的Id
绑定到mat-option ,您也必须将id
绑定到mat-select ,而不是整个项目、标题或任何其他项目,只有相同的字段。
但是你需要通过绑定来做到这一点 []
我非常仔细地遵循了上述内容,但仍然无法获得选择的初始值。
原因是虽然我的绑定值在打字稿中被定义为字符串,但我的后端 API 返回的是一个数字。
Javascript 松散类型只是在运行时更改了类型(没有错误),这阻止了对初始值的选择。
组件
myBoundValue: string;
模板
<mat-select [(ngModel)]="myBoundValue">
解决方案是更新 API 以返回字符串值。
一个非常简单的方式实现这一目标是使用formControl
具有缺省值,一个内部FormGroup
例如(可选)。 这是使用单元选择器到区域输入的示例:
ts
H_AREA_UNIT = 1;
M_AREA_UNIT = 2;
exampleForm: FormGroup;
this.exampleForm = this.formBuilder.group({
areaUnit: [this.H_AREA_UNIT],
});
html
<form [formGroup]="exampleForm">
<mat-form-field>
<mat-label>Unit</mat-label>
<mat-select formControlName="areaUnit">
<mat-option [value]="H_AREA_UNIT">h</mat-option>
<mat-option [value]="M_AREA_UNIT">m</mat-option>
</mat-select>
</mat-form-field>
</form>
当页面加载时,我在绑定第一个选项时遇到问题。 下面有帮助我的解决方案
.html
<mat-form-field appearance="outline">
<mat-select #teamDropdown
[ngModel]="selectedGroupId" (selectionChange)="selectedGroupId=$event.value">
<mat-option value=undefined>Please Select</mat-option>
<mat-option *ngFor="let grp of groups" [value]="grp.groupsId">
{{grp.groupName}}
</mat-option>
</mat-select>
</mat-form-field>
.ts
@ViewChild('teamDropdown') teamDropdown: MatSelect;
ngAfterViewInit() {
setTimeout(() => {
this.selectTeamDropdown.options.first.select();
});
}
数字和字符串之间的比较使用 false ,因此,将您选择的值转换为 ngOnInit 中的字符串,它将起作用。
我有同样的问题,我用枚举填充了 mat-select,使用
Object.keys(MyAwesomeEnum).filter(k => !isNaN(Number(k)));
我有我想选择的枚举值......
我花了几个小时苦苦思索,试图找出它不起作用的原因。 我在渲染了 mat-select 中使用的所有变量、keys 集合和选定的...这是一个数字) 1=="1" 是假的,因此没有选择任何内容。
因此,解决方案是将您选择的值转换为ngOnInit 中的字符串,它会起作用。
我这样做了。
<div>
<mat-select [(ngModel)]="selected">
<mat-option *ngFor="let option of options"
[value]="option.id === selected.id ? selected : option">
{{ option.name }}
</mat-option>
</mat-select>
</div>
通常你可以做[value]="option"
,除非你从某个数据库中得到你的选项?? 我认为要么是获取数据的延迟导致它不起作用,要么即使它们相同,获取的对象在某些方面也有所不同?? 奇怪的是,它最有可能是后者,因为我也尝试过[value]="option === selected ? selected : option"
但它没有用。
TS
optionsFG: FormGroup;
this.optionsFG = this.fb.group({
optionValue: [null, Validators.required]
});
this.optionsFG.get('optionValue').setValue(option[0]); //option is the arrayName
HTML
<div class="text-right" [formGroup]="optionsFG">
<mat-form-field>
<mat-select placeholder="Category" formControlName="optionValue">
<mat-option *ngFor="let option of options;let i =index" [value]="option">
{{option.Value}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
public options2 = [ {"id": 1, "name": "a"}, {"id": 2, "name": "b"} ] YourFormGroup = FormGroup; mode: 'create' | 'update' = 'create'; constructor(@Inject(MAT_DIALOG_DATA) private defaults: defautValuesCpnt, private fb: FormBuilder, private cd: ChangeDetectorRef) { } ngOnInit() { if (this.defaults) { this.mode = 'update'; } else { this.defaults = {} as Cpnt; } this.YourFormGroup.patchValue({ ... fCtrlName: this.options2.find(x => x.name === this.defaults.name).id, ... }); this.YourFormGroup = this.fb.group({ fCtrlName: [ , Validators.required] }); }
<div> <mat-select formControlName="fCtrlName"> <mat-option *ngFor="let option of options2" value="{{ option.id }}"> {{ option.name }} </mat-option> </mat-select> </div>
唯一的解决方案是您的表单控件或 mat select 标签中的 Ng 模型值必须与分配给选项标签中的值的文本匹配这里是 Ts 文件
selectedFood = 'Tacos';
模板
<mat-form-field appearance="fill">
<mat-label>Favorite Food</mat-label>
<mat-select [(value)]="selectedFood">
<mat-option value=''>---------</mat-option>
<mat-option value='Tacos'>Tacos</mat-option>
<mat-option value='Pizza'>Pizza</mat-option>
</mat-select>
</mat-form-field>
<p>You selected: {{selectedFood}}</p>
在使用角度材质选择时,使用compareWith函数比较对象是一个很好的做法。 如果您想了解更多关于如何使用 mat-select 的信息,您可以查看以下链接: 比较函数在角度材料选择中的重要性
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.