may I set selected Value by formcontrol i Have this snipped in my html document
<!--segment panel-->
<fa-expansion-panel [title]="'Сегмент'">
<mat-form-field
floatLabel="always"
>
<mat-label>Обрані пункти</mat-label>
<mat-select [formControlName]="'segments'" multiple>
<mat-option
*ngFor="let segment of segmentList"
[value]="segment"
>{{ segment.segName }}</mat-option
>
</mat-select>
</mat-form-field>
</fa-expansion-panel>
<!--end segment panel-->
in the ts file i have this form control
segments = new FormControl()
this is the segments list
segmentList = [
{id: 1, segName: 'hello'},
{id: 2, segName: 'by'},
{id: 3, segName: 'welcome'},
]
here I'm changing the form control value
segments.setValue([{id: 2, segName: 'by'}, {id: 3, segName: 'welcome'}])
the code compiles successfully, but no items are selected in the select box
CodePudding user response:
It probably has to do with how Javascript handles objects. Let me explain.
Object in javascript are checked by reference. So let's say your segmentList
segmentList = [
{id: 1, segName: 'hello'},
{id: 2, segName: 'by'},
{id: 3, segName: 'welcome'},
]
is equivalent to these references:
segmentList = [
hash1abc,
hash2edf,
hash3ghi,
];
so when you select something, the formControl becomes equal to hashxxx
reference, and it is shown by the value of hash1abc.segName
.
If you follow me so far, you'll find the solution easily:
so when you do
segments.setValue([{id: 2, segName: 'by'}, {id: 3, segName: 'welcome'}])
you are doing:
segments.setValue([diffHashabc, diffHashcef])
your objects look the same, but they are indeed not the same ones that are on the list. So your mat-form does not recognize them. This happens because the array inside the setValue
is a different set of Objects with different references.
I would try two things (unsure if these would solve the issue though), instead of writing them by hand, try getting them from your segmentList
through filter
or find
.
Or try to use trackBy: segmentFn
on your ngFor so it reads the id of the objects to know which one to render, instead of Object reference. Unsure if this would work but might. You would also need to add to the component segmentFn = (index, segment) => segment.id;
for it to work
CodePudding user response:
Try this:
<mat-select [formControlName]="'segments'" multiple
[compareWith]="compareObjects">
<mat-option
*ngFor="let segment of segmentList"
[value]="segment">
{{ segment.segName }}
</mat-option>
</mat-select>
in the ts
file define the compareObjects
like:
compareObjects(o1: any, o2: any): boolean {
return o1.segName === o2.segName && o1.id === o2.id;
}
CodePudding user response:
You've created different objects, whereas Angular Material will compare by reference. Set the form by referencing the original objects:
segments.setValue([this.segmentList[1], this.segmentList[2]])