[英]Issue of select in angular2
Please see my plunker code i have created. 请查看我创建的插件代码。 when i click toggle show button 2 times i should get selected item.
当我单击切换显示按钮两次时,我应该会选择项目。
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 ...
}
}
With this template and changeShow()
function: 使用此模板和
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
...
}
Notice that when you click the button (and changeShow()
method is called), you are recreating the array the <select>/<option>
s point to. 注意,单击按钮(并
changeShow()
方法)时,将重新创建 <select>/<option>
指向的数组。
Since the selectedDeviceObj
property pointed to an element of the previous deviceObjects
, the <select>
now has no value selected. 由于
selectedDeviceObj
属性指向以前的deviceObjects
的元素,因此<select>
现在没有选择任何值。
It may seem strange, but the change detection uses strict equality, or object identity, ( ===
) to compare the objects. 看起来有些奇怪,但是更改检测使用严格的相等性或对象标识(
===
)比较对象。 Thus the {name: 2}
in the original deviceObjects
is not the same {name: 2}
in the new deviceObjects
(they may have the same values, but they are not the exactly same object). 因此,
{name: 2}
在原始deviceObjects
是不一样的{name: 2}
在新deviceObjects
(它们可以具有相同的值,但它们不是完全相同的对象)。
So, if you remove the this.deviceObjects = ...
line on changeShow()
, the <select>
should keep its selection: 因此,如果删除
changeShow()
上的this.deviceObjects = ...
行, <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;
}
...
}
See demo plunker here . 在这里查看演示插件 。
If you really need to change the whole array at each click, you can then try to update the selectedDeviceObj
at each click as well: 如果确实需要在每次单击时更改整个数组,则也可以尝试在每次单击时更新
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)
);
}
...
}
See demo plunker here . 在这里查看演示插件 。
The updateSelectedDeviceObj()
function above compares the objects by their JSON string. 上面的
updateSelectedDeviceObj()
函数通过JSON字符串比较对象。 Array.prototype.find()
returns the first object in the array that satisfy the criteria (which is "JSON equality"). Array.prototype.find()
返回数组中满足条件(即“ JSON相等”)的第一个对象。
Notice why this works: {name: 2} === {name: 2}
is false
(they are not the same object, but JSON.stringify({name: 2}) === JSON.stringify({name: 2})
is true
(their JSON equivalent string is the same). 请注意为什么这样做:
{name: 2} === {name: 2}
为false
(它们不是同一对象,但是JSON.stringify({name: 2}) === JSON.stringify({name: 2})
为true
(它们的JSON等效字符串相同)。
If you have another way to tell if the objects are the same (an ID-like property, maybe), then definitely use it. 如果您有另一种判断对象是否相同的方法(可能是类似ID的属性),则一定要使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.