I just recently figured out that there is an alternative for value
property on OPTION part of the SELECT, namely ngValue
. The docs really lack documentation about this (all I could find: https://angular.io/docs/ts/latest/api/forms/index/NgSelectOption-directive.html). Anyway, the idea is that when you use an object for the ngModel
, you can use ngValue
and it works well. Otherwise, only e.g. ID is updated. If we're having just an array of strings, value is sufficient. Here are the examples:
{{myModel | json}}
<select [(ngModel)]="myModel">
<option *ngFor="let i of items" [ngValue]="i">{{i.value}}</option>
</select>
<br /><br />
{{mySimpleModel}}
<select [(ngModel)]="mySimpleModel">
<option *ngFor="let i of simpleItems" [value]="i">{{i}}</option>
</select>
While this works as expected, there's a distinctive differences between the two: if using ngValue
, the predefined value is not selected in the drop down, whereas for the primitive types, the value is selected on loading. E.g.:
items: any[] = [{id: 1, value: 'item1'}, {id: 2, value: 'item2'}, {id: 3, value: 'item3'}];
myModel: any = {id: this.items[1].id , value: this.items[1].value};
simpleItems: string[] = ['item1', 'item2', 'item3'];
mySimpleModel: string = this.simpleItems[1];
See example here: https://plnkr.co/edit/JBrtmx7QkPZztBjaqYkS?p=preview So, why does Angular set the default value for strings, but not for objects? And what is the most elegant workaround?
You don't need a "workaround" for that. When you do this
myModel = {id: this.items[1].id , value: this.items[1].value};
you are creating a new object which has the same values as this.items[1]
but it is not the same object, it's a new one.
const items = [{id: 1, value: 'item1'}, {id: 2, value: 'item2'}, {id: 3, value: 'item3'}]
const myModel = {id: 2, value: 'item2'};
console.log(items[1] === myModel);
that is the reason why your select can't find that value in the <option>
list.
In order to fix that, you have to use a proper reference
items = [
{id: 1, value: 'item1'},
{id: 2, value: 'item2'},
{id: 3, value: 'item3'}
];
myModel = this.items[1]
plunkr
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With