Tengo un mat-select donde las opciones son todos objetos definidos en un array. Estoy tratando de establecer el valor por defecto a una de las opciones, sin embargo se está dejando seleccionado cuando la página se rinde.
Mi archivo typescript contiene:
public options2 = [
{"id": 1, "name": "a"},
{"id": 2, "name": "b"}
]
public selected2 = this.options2[1].id;
Mi archivo HTML contiene:
<div>
<mat-select
[(value)]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
He probado a poner selected2
y el value
en mat-option
tanto al objeto como a su id, y he probado a usar tanto [(value)]
como [(ngModel)]
en el mat-select
, pero ninguno funciona.
Estoy usando la versión de material 2.0.0-beta.10
Utilice un enlace para el valor en su plantilla.
value="{{ option.id }}"
debe ser
[value]="option.id"
Y en su valor seleccionado utilice ngModel
en lugar de value
.
<mat-select [(value)]="selected2">
debe ser
<mat-select [(ngModel)]="selected2">
Código completo:
<div>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</div>
Por otro lado, a partir de la versión 2.0.0-beta.12 el material select acepta ahora un elemento mat-form-field
como elemento padre para que sea consistente con los otros controles de entrada de material. Sustituya el elemento div
por el elemento mat-form-field
después de actualizar.
<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>
Estoy usando Angular 5 y formularios reactivos con mat-select y no he podido conseguir que ninguna de las soluciones anteriores muestre el valor inicial.
Tuve que añadir [compareWith] para lidiar con los diferentes tipos que se utilizan dentro del componente mat-select. Internamente, parece que mat-select utiliza un array para mantener el valor seleccionado. Es probable que esto permita que el mismo código funcione con múltiples selecciones si ese modo está activado.
Aquí'está mi solución:
Form Builder para inicializar el control del formulario:
this.formGroup = this.fb.group({
country: new FormControl([ this.myRecord.country.id ] ),
...
});
A continuación, implemente la función compareWith en su componente:
compareIds(id1: any, id2: any): boolean {
const a1 = determineId(id1);
const a2 = determineId(id2);
return a1 === a2;
}
A continuación, cree y exporte la función determineId (tuve que crear una función independiente para que mat-select pudiera utilizarla):
export function determineId(id: any): string {
if (id.constructor.name === 'array' && id.length > 0) {
return '' + id[0];
}
return '' + id;
}
Por último, añada el atributo compareWith a su 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>
Debería vincularlo como [valor]
en la mat-option
como se indica a continuación,
<mat-select placeholder="Panel color" [(value)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">
{{ option.name }}
</mat-option>
</mat-select>