在角度2

时间:2016-08-02 15:17:47

标签: javascript html angularjs angular

请参阅我创建的我的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 ...

  }
}

1 个答案:

答案 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;
  }
  ...
}

请参阅demo plunker here

更新(每条评论):

如果您确实需要在每次点击时更改整个数组,那么您也可以尝试在每次点击时更新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)
                             );
  }
  ...
}

请参阅demo plunker here

上面的updateSelectedDeviceObj()函数通过JSON字符串比较对象。 Array.prototype.find()返回数组中满足条件的第一个对象(即“JSON相等”)。

请注意为什么会这样:{name: 2} === {name: 2}false(它们不是相同的对象,但JSON.stringify({name: 2}) === JSON.stringify({name: 2})true(它们的JSON等价物)字符串是相同的。)

如果您有另一种方法来判断对象是否相同(可能是类似ID的属性),那么一定要使用它。