Reputation: 38171
I have an array of objects(named users) which will be shown as options of dropdownlist
. and I have another objects list(named selectedUsers and is saved in backend) which is used to initialize the dropdownlist
.
array:
users = [
{
id: 2,
name: 'name2'
},{
id: 2,
name: 'name2'
},{
id: 3,
name: 'name3'
}
];
selectedUsers3 = [
{
id: 1,
name: 'name1'
},{
id: 2,
name: 'name2'
}
];
I'm facing a wired situation which is when I bind Object
to select options
by [ngValue]
, and bind a function to [selected]
which will check whether the current option exists in selectedUsers
.
I can see the function is retrieved and the result is returned true/false as excepted, but the options keeps unselected.
template:
<select multiple [(ngModel)]="selectedUsers3">
<option *ngFor="let user of users" [selected]="checkExist(user)" [ngValue]="user">{{user.name}}</option>
</select>
function in component:
checkExist(user) {
return this.selectedUsers3.findIndex(selUser => selUser.id === user.id) > -1;
//return this.selectedUsers3.filter(selUser => selUser.id === user.id).length > 0;
}
mention that I used Array.filter
or Array.findIndex
to check whether the data exists, and the result is correct.
Please refer this demo with the third dropdownlist
, and check where am I doing something wrong? or am I missing something about [selected]
? I hope someone can explain clearly about this.
UPD:
with @Günter Zöchbauer's help, this situation can be solved by using compareWith
directive(refer his answer) no matter single select
or multi select
, but I'm still confused why they work well alongside but fail together and still trying to figure out the reason.
Upvotes: 3
Views: 7102
Reputation: 38171
Answer to conflicts between [(ngModel)] and [selected]
after some research and debug, I find that while using ngModel
on select
, angular will run it's own SelectMultipleControlValueAccessor
for select
and own directive
for option
of select
which lead selected
to be ignored.
In the third example(example plunker), after ngModel
is used, although function bind to [selected]
will be called, but it's result is simply ignored.
Comments
[(ngModel)]
and [ngValue]
with same instance of objects.compareWith
directive, see Gunter' s anwserSelectControlValueAccessor
and directive
for option
.New Info:
See also this issue for more information.
Upvotes: 1
Reputation: 657158
selected
is not supported with [(ngModel)]="selectedUser3"
.
To make an item selected, the value
(for string only) or ngValue
property value needs to match the value in selectedUser3
.
this.selectedUser3 = this.users[2];
By default only object identity is checked, therefore another object instance with the same properties and values doesn't match.
You can customize comparison using compareWith
https://angular.io/docs/ts/latest/api/forms/index/SelectControlValueAccessor-directive.html
<select [compareWith]="compareFn" [(ngModel)]="selectedCountries"> <option *ngFor="let country of countries" [ngValue]="country"> {{country.name}} </option> </select> compareFn(c1: Country, c2: Country): boolean { return c1 && c2 ? c1.id === c2.id : c1 === c2; }
Upvotes: 8