Recientemente descubrí que hay una alternativa para la propiedad de value en la parte OPCIÓN de SELECCIONAR, a saber, ngValue . Los documentos realmente carecen de documentación sobre esto (todo lo que pude encontrar: https://angular.io/docs/ts/latest/api/forms/index/NgSelectOption-directive.html ). De todos modos, la idea es que cuando usa un objeto para ngModel , puede usar ngValue y funciona bien. De lo contrario, solo se actualiza, por ejemplo, ID. Si solo tenemos una matriz de cadenas, el valor es suficiente. Aquí están los ejemplos:
{{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> Si bien esto funciona como se esperaba, existen diferencias distintivas entre los dos: si usa ngValue , el valor predefinido no se selecciona en el menú desplegable, mientras que para los tipos primitivos, el valor se selecciona al cargar. P.ej:
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];Vea el ejemplo aquí: https://plnkr.co/edit/JBrtmx7QkPZztBjaqYkS?p=preview Entonces, ¿por qué Angular establece el valor predeterminado para las cadenas, pero no para los objetos? ¿Y cuál es la solución más elegante?
No necesita una "solución alternativa" para eso. cuando haces esto
myModel = {id: this.items[1].id , value: this.items[1].value}; está creando un nuevo objeto que tiene los mismos valores que this.items[1] pero no es el mismo objeto, es uno nuevo.
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); esa es la razón por la que su selección no puede encontrar ese valor en la lista <option> .
Para arreglar eso, tienes que usar una referencia adecuada
items = [ {id: 1, value: 'item1'}, {id: 2, value: 'item2'}, {id: 3, value: 'item3'} ]; myModel = this.items[1]Para obtener la opción seleccionada por defecto usando [ngValue] puede usar [compareWith]. Simplemente cambie en el método compareObj el atributo correcto para el Objeto que está comparando.
<select [compareWith]="compareObj" [(ngModel)]="selectedObject"> <option *ngFor="let object of objects" [ngValue]="object"> {{object.name}} </option> </select> compareObj(o1: Object, o2: Object) { return o1.id === o2.id; }