¿Puedo establecer el valor seleccionado por formcontrol? Tengo esto cortado en mi documento html
<!--segment panel--> <fa-expansion-panel class="expansion-panel-class" [title]="'Сегмент'"> <mat-form-field floatLabel="always" class="segment-field fa-input-field full-width" > <mat-label>Обрані пункти</mat-label> <mat-select [formControlName]="'segments'" multiple> <mat-option class="mat-options" *ngFor="let segment of segmentList" [value]="segment" >{{ segment.segName }}</mat-option > </mat-select> </mat-form-field> </fa-expansion-panel> <!--end segment panel-->en el archivo ts tengo este control de formulario
segments = new FormControl()esta es la lista de segmentos
segmentList = [ {id: 1, segName: 'hello'}, {id: 2, segName: 'by'}, {id: 3, segName: 'welcome'}, ]aquí estoy cambiando el valor del control de formulario
segments.setValue([{id: 2, segName: 'by'}, {id: 3, segName: 'welcome'}])el código se compila correctamente, pero no se seleccionan elementos en el cuadro de selección
Probablemente tenga que ver con la forma en que Javascript maneja los objetos. Dejame explicar.
Los objetos en javascript se verifican por referencia. Así que digamos su lista de segmentList
segmentList = [ {id: 1, segName: 'hello'}, {id: 2, segName: 'by'}, {id: 3, segName: 'welcome'}, ]es equivalente a estas referencias:
segmentList = [ hash1abc, hash2edf, hash3ghi, ]; por lo tanto, cuando selecciona algo, formControl se vuelve igual a la referencia hashxxx , y se muestra con el valor de hash1abc.segName .
Si me sigues hasta ahora, encontrarás la solución fácilmente:
así que cuando lo hagas
segments.setValue([{id: 2, segName: 'by'}, {id: 3, segName: 'welcome'}])Tú lo estás haciendo:
segments.setValue([diffHashabc, diffHashcef]) sus objetos se ven iguales, pero de hecho no son los mismos que están en la lista. Así que tu mat-form no los reconoce. Esto sucede porque la matriz dentro de setValue es un conjunto diferente de objetos con diferentes referencias.
Intentaría dos cosas (sin embargo, no estoy seguro de si esto resolvería el problema), en lugar de escribirlas a mano, intente obtenerlas de su segmentList a través de filter o find .
O intente usar trackBy: segmentFn en su ngFor para que lea la identificación de los objetos para saber cuál representar, en lugar de la referencia del objeto. No estoy seguro de si esto funcionaría, pero podría. También necesitaría agregar al componente segmentFn = (index, segment) => segment.id; para que funcione
Prueba esto:
<mat-select [formControlName]="'segments'" multiple [compareWith]="compareObjects"> <mat-option class="mat-options" *ngFor="let segment of segmentList" [value]="segment"> {{ segment.segName }} </mat-option> </mat-select> en el archivo ts defina los compareObjects como:
compareObjects(o1: any, o2: any): boolean { return o1.segName === o2.segName && o1.id === o2.id; }Ha creado diferentes objetos, mientras que Angular Material se comparará por referencia. Configure el formulario haciendo referencia a los objetos originales:
segments.setValue([this.segmentList[1], this.segmentList[2]])