请参阅我创建的我的plunker代码。当我点击切换显示按钮2次我应该选择项目。
import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `<div *ngIf="show"><select [(ngModel)]="selectedDeviceObj" name="sel3">
<option [ngValue]="i" *ngFor="let i of deviceObjects">{{i.name}}</option>
</select></div>
{{selectedDeviceObj | json}}
<br/><br/><br/>
<button (click)="changeShow()">toggle show</button>
`
//directives: []
})
export class AppComponent {
changeShow(){
this.deviceObjects = [{name: 1}, {name: 2}, {name: 3}];
this.show=!this.show;
}
show=true;
title = "Angular 2 RC.4 - select";
devices = 'one two three'.split(' ');
selectedDevice = 'two';
deviceObjects = [{name: 1}, {name: 2}, {name: 3}];
selectedDeviceObj = this.deviceObjects[1];
//constructor() { console.clear(); }
onChange(newValue) {
console.log(newValue);
this.selectedDevice = newValue;
// ... do other stuff here ...
}
onChangeObj(newObj) {
console.log(newObj);
this.selectedDeviceObj = newObj;
// ... do other stuff here ...
}
}
答案 0 :(得分:1)
使用此模板和changeShow()
功能:
@Component({
...
template: `<div *ngIf="show"><select [(ngModel)]="selectedDeviceObj" name="sel3">
<option [ngValue]="i" *ngFor="let i of deviceObjects">{{i.name}}</option>
</select></div>
...
<button (click)="changeShow()">toggle show</button>
`
...
})
export class AppComponent {
changeShow(){
this.deviceObjects = [{name: 1}, {name: 2}, {name: 3}]; // <---- recreating the array!
this.show=!this.show;
}
...
deviceObjects = [{name: 1}, {name: 2}, {name: 3}]; // <--- the "old" array
selectedDeviceObj = this.deviceObjects[1]; // <--- points to an object of the "old" array
...
}
请注意,当您单击按钮(并调用changeShow()
方法)时,您重新创建 <select>/<option>
指向的数组。
由于selectedDeviceObj
属性指向前一个deviceObjects
的元素,因此<select>
现在没有选择值。
看起来很奇怪,但更改检测使用严格相等或对象标识(===
)来比较对象。因此,原始{name: 2}
中的deviceObjects
与新{name: 2}
中的deviceObjects
相同(它们可能具有相同的值,但它们是不完全相同的对象)。
因此,如果您移除this.deviceObjects = ...
上的changeShow()
行,则<select>
应保留其选择权:
@Component({
...
template: `<div *ngIf="show"><select [(ngModel)]="selectedDeviceObj" name="sel3">
<option [ngValue]="i" *ngFor="let i of deviceObjects">{{i.name}}</option>
</select></div>
...
<button (click)="changeShow()">toggle show</button>
`
...
})
export class AppComponent {
changeShow(){
this.show=!this.show;
}
...
}
如果您确实需要在每次点击时更改整个数组,那么您也可以尝试在每次点击时更新selectedDeviceObj
:
export class AppComponent {
changeShow(){
this.deviceObjects = [{name: 1}, {name: 2}, {name: 3}];
this.show=!this.show;
this.updateSelectedDeviceObj();
}
updateSelectedDeviceObj() {
// tries to find in the new array (this.deviceObjects) if there's any object equal to
// the this.selectedDeviceObj. If so, sets it as this.selectedDeviceObj.
// Uses JSON.stringify() to tell if they are the same. If you have a simpler way to see
// if the objects are the same (an ID-like property, maybe), then definitely use it.
let jsonSelectedDeviceObj = JSON.stringify(this.selectedDeviceObj);
this.selectedDeviceObj =
this.deviceObjects.find(deviceObject =>
jsonSelectedDeviceObj === JSON.stringify(deviceObject)
);
}
...
}
上面的updateSelectedDeviceObj()
函数通过JSON字符串比较对象。 Array.prototype.find()
返回数组中满足条件的第一个对象(即“JSON相等”)。
请注意为什么会这样:{name: 2} === {name: 2}
是false
(它们不是相同的对象,但JSON.stringify({name: 2}) === JSON.stringify({name: 2})
是true
(它们的JSON等价物)字符串是相同的。)
如果您有另一种方法来判断对象是否相同(可能是类似ID的属性),那么一定要使用它。