trigger example event change angular typescript angular-material2

example - Material angular: mat-select no selecciona el valor predeterminado



mat-select-trigger (10)

¡Prueba esto!

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

Tengo un mat-select donde las opciones son todos los objetos definidos en una matriz. Estoy tratando de establecer el valor predeterminado en una de las opciones, sin embargo, se deja seleccionado cuando se presenta la página.

Mi archivo mecanografiado 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>

Intenté configurar selected2 y el value en mat-option tanto para el objeto como para su id, e intenté usar tanto [(value)] como [(ngModel)] en mat-select , pero ninguno funciona.

Estoy usando la versión de material 2.0.0-beta.10


Como ya se mencionó en Angular 6, el uso de ngModel en formas reactivas está en desuso (y se elimina en Angular 7), por lo que modifiqué la plantilla y el componente de la siguiente manera.

La plantilla:

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

Las partes principales del componente (se onChanges y otros detalles):

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

Tenga en cuenta this.filter.setValue (this.selected) en ngOnInit arriba.

Parece funcionar en Angular 6.


Debería vincularlo como [value] en la mat-option como se muestra 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>

DEMO EN VIVO


Estoy usando Angular 5 y formas reactivas con mat-select y no pude obtener ninguna de las soluciones anteriores para mostrar el valor inicial.

Tuve que agregar [compareWith] para tratar con los diferentes tipos que se utilizan dentro del componente mat-select. Internamente, parece que mat-select usa una matriz para mantener el valor seleccionado. Es probable que esto permita que el mismo código funcione con varias selecciones si ese modo está activado.

Documento de control de selección angular

Aquí está mi solución:

Form Builder para inicializar el control de formulario:

this.formGroup = this.fb.group({ country: new FormControl([ this.myRecord.country.id ] ), ... });

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

Luego, cree y exporte la función determineId (tuve que crear una función independiente para que mat-select pudiera usarla):

export function determineId(id: any): string { if (id.constructor.name === ''array'' && id.length > 0) { return '''' + id[0]; } return '''' + id; }

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


La solución para mí fue:

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

Usando objeto: {id: número, detalle: cadena}


Lo hice como en estos ejemplos. Intenté establecer el valor de mat-select en el valor de una de las opciones de mat. Pero falló.

Mi error fue hacer [(valor)] = "someNumberVariable" en una variable de tipo numérico, mientras que las de las opciones de mat eran cadenas. Incluso si tuvieran el mismo aspecto en la plantilla, no seleccionaría esa opción.

Una vez que analicé el someNumberVariable en una cadena, todo estuvo totalmente bien.

Por lo tanto, parece que necesita tener los valores mat-select y mat-option no solo sean el mismo número (si está presentando números) sino que también deben ser de tipo cadena.


Mi solución es un poco complicada y más simple.

<div> <mat-select [placeholder]="selected2"> <mat-option *ngFor="let option of options2" value="{{ option.id }}"> {{ option.name }} </mat-option> </mat-select> </div>

Acabo de hacer uso del marcador de posición . El color predeterminado del marcador de posición del material es light gray . Para que parezca que la opción está seleccionada, simplemente manipulé el CSS de la siguiente manera:

::ng-deep .mat-select-placeholder { color: black; }


Simplemente puede implementar su propia función de comparación

[compareWith]="compareItems"

Ver también el docu . Entonces el código completo se vería así:

<div> <mat-select [(value)]="selected2" [compareWith]="compareItems"> <mat-option *ngFor="let option of options2" value="{{ option.id }}"> {{ option.name }} </mat-option> </mat-select> </div>

y en el archivo mecanografiado:

compareItems(i1, i2) { return i1 && i2 && i1.id===i2.id; }


Use un enlace para el valor en su plantilla.

value="{{ option.id }}"

debiera ser

[value]="option.id"

Y en su valor seleccionado use ngModel lugar de value .

<mat-select [(value)]="selected2">

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

En una nota al margen a partir de la versión 2.0.0-beta.12, la selección de material ahora acepta un elemento mat-form-field como elemento padre, por lo que es coherente con los otros controles de entrada de material. Reemplace el elemento div con 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>


Utilice compareWith , una función para comparar los valores de las opciones con los valores seleccionados. ver aquí: https://material.angular.io/components/select/api#MatSelect

Para un objeto de la siguiente estructura:

listOfObjs = [{ name: ''john'', id: ''1''}, { name: ''jimmy'', id: ''2''},...]

Defina marcado como este:

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

Y defina una función de comparación como esta:

compareObjects(o1: any, o2: any): boolean { return o1.name === o2.name && o1.id === o2.id; }