以编程方式设置 <mat-select> 的值

Posted

技术标签:

【中文标题】以编程方式设置 <mat-select> 的值【英文标题】:Set value of <mat-select> programmatically 【发布时间】:2018-07-25 14:51:51 【问题描述】:

我正在尝试以编程方式设置 2 个字段 &lt;input matInput&gt; abnd &lt;mat-select&gt; 的值。对于文本输入,一切都按预期工作,但是对于视图上的&lt;mat-select&gt;,这个字段就像它在null 上的值一样。但是,如果我调用console.log(productForm.controls['category'].value,它会打印出我以编程方式设置的正确值。我错过了什么吗?

代码如下:

表单配置:

productForm = new FormGroup(
    name: new FormControl('', [
        Validators.required
    ]),
    category: new FormControl('', [
        Validators.required
    ]),
);

设定值:

ngOnInit() 
    this.productForm.controls['name'].setValue(this.product.name);
        this.productForm.controls['category'].setValue(this.product.category);
    

html:

<mat-form-field>
    <mat-select [formControlName]="'category'"
                [errorStateMatcher]="errorStateMatcher">
        <mat-option *ngFor="let category of categories" [value]="category">
            category.name
        </mat-option>
    </mat-select>
</mat-form-field>

【问题讨论】:

【参考方案1】:

Angular mat-select 通过引用比较该对象与mat-select 中的所有可用对象之间的引用。结果,它无法选择您在类别字段中设置的项目。因此,您必须实现比较函数以根据需要比较任何列表项的属性,然后将此函数传递给@的[compareWith]属性 987654326@. 最后,这是最终标记和脚本的快照:

<mat-form-field>
    <mat-select [formControlName]="category" [compareWith]="compareCategoryObjects">
        <mat-option *ngFor="let category of categories" [value]="category">
            category.name
        </mat-option>
    </mat-select>
</mat-form-field>

在组件类中:

compareCategoryObjects(object1: any, object2: any) 
    return object1 && object2 && object1.id == object2.id;

现在它将选择您为该字段设置的项目 - 或多选项目。

参考:https://github.com/angular/material2/issues/10214

工作示例:https://stackblitz.com/edit/angular-material2-issue-t8rp7j

【讨论】:

这是真正的正确答案。 OP 接受的答案有效,因为 OP 将对象绑定更改为 mat-select 为 Id 字段,该字段属于 Angular 中的原始类型。因此,“compareWith”的工作原理是内置在 Angular 中的。如果需要将 mat-select 绑定到对象,则需要定义 compareWith。与 Java 不同,如果您希望事情真正正常工作,您需要实现 equals 和 hashcode。【参考方案2】:

通过将 &lt;mat-option&gt; 的值从 category 对象更改为其 ID 解决了此问题。

<mat-form-field>
<mat-select [formControlName]="'category'"
        [errorStateMatcher]="errorStateMatcher">
<mat-option *ngFor="let category of categories" [value]="category.id">
    category.name
</mat-option>
</mat-select>
</mat-form-field>

及设定值:

this.productForm.controls['category'].setValue(this.product.category.id);

【讨论】:

【参考方案3】:

使用对象实现此目的的方法是像这样更改标记:

<mat-select [formControlName]="'category'"
        [errorStateMatcher]="errorStateMatcher" [compareWith]="compareFn">
<mat-option *ngFor="let category of categories" [value]="category">
    category.name
</mat-option>
</mat-select>

然后在组件中

compareFn(x: Category, y: Category): boolean 
return x && y ? x.id === y.id : x === y;

【讨论】:

【参考方案4】:

我认为在这里你应该使用FormGroup.setValue

根据您的代码,

this.productForm.setValue(
name: this.product.name,
category: this.product.category
);

更多信息请参考documentation

【讨论】:

以上是关于以编程方式设置 <mat-select> 的值的主要内容,如果未能解决你的问题,请参考以下文章

mat-select inside mat-sidenav 在 sidenav 打开时自动聚焦

<mat-select> 多选(formControl)

Angular 2材料垫选择以编程方式打开/关闭

如何以编程方式将所有 <object> 设置为将 wmode 设置为不透明?

角度材料将图像放在 <mat-select> 的选定值上

为角材料的 <mat-select> 组件实现搜索过滤器