如何在Angular 2的“选择”中获得新选择?


372

我正在使用Angular 2(TypeScript)。

我想对新选择进行某些操作,但是我得到的onChange()总是最后一个选择。如何获得新选择?

<select [(ngModel)]="selectedDevice" (change)="onChange($event)">
   <option *ngFor="#i of devices">{{i}}</option>
</select>
onChange($event) {
    console.log(this.selectedDevice);
    // I want to do something here with the new selectedDevice, but what I
    // get here is always the last selection, not the one I just selected.
}

Answers:


749

如果您不需要双向数据绑定:

<select (change)="onChange($event.target.value)">
    <option *ngFor="let i of devices">{{i}}</option>
</select>

onChange(deviceValue) {
    console.log(deviceValue);
}

对于双向数据绑定,请分开事件和属性绑定:

<select [ngModel]="selectedDevice" (ngModelChange)="onChange($event)" name="sel2">
    <option [value]="i" *ngFor="let i of devices">{{i}}</option>
</select>
export class AppComponent {
  devices = 'one two three'.split(' ');
  selectedDevice = 'two';
  onChange(newValue) {
    console.log(newValue);
    this.selectedDevice = newValue;
    // ... do other stuff here ...
}

如果devices是对象数组,则绑定到ngValue而不是value

<select [ngModel]="selectedDeviceObj" (ngModelChange)="onChangeObj($event)" name="sel3">
  <option [ngValue]="i" *ngFor="let i of deviceObjects">{{i.name}}</option>
</select>
{{selectedDeviceObj | json}}
export class AppComponent {
  deviceObjects = [{name: 1}, {name: 2}, {name: 3}];
  selectedDeviceObj = this.deviceObjects[1];
  onChangeObj(newObj) {
    console.log(newObj);
    this.selectedDeviceObj = newObj;
    // ... do other stuff here ...
  }
}

Plunker-不使用<form>
Plunker-使用<form>并使用新的表单API


确实是对的,但是ngModel在这里的作用是什么,您仍然会困惑吗?
Pardeep Jain

1
@PardeepJain,与NgModel进行双向数据绑定会导致Angular为1)selectedDevice用户选择其他项时自动更新,以及2)如果我们设置的值selectedDevice,则NgModel将自动更新视图。由于我们也希望收到更改通知,因此添加了(change)事件绑定。我们不必这样做,...应该可以将双向数据绑定分解为[ngModel]="selectedDevice" and (ngModelChange)="onChange($event)",但是正如我发现的那样,onChange()每次选择列表的更改都会被调用两次。
Mark Rajcok 2015年

好吧,谢谢。我想要得到的值:<option *ngFor="#course of course_array #i=index" #newone value={{course.id}} >{{course.course_name}}</option> course.course_namecourse.id两个我怎么可以给这两个通过(其他城市)功能?
Pardeep Jain

1
@HongboMiao,特殊$event变量/符号是Angular模板语句具有的“语句上下文”的一部分。如果不是我写的(ngModelChange)="onChange('abc')"话,newValue将得到字符串abc。这只是正常的JavaScript函数调用。
Mark Rajcok '16

2
@HongboMiao,如果您有对象数组,请使用[ngValue]。如果您具有原始类型(字符串,布尔值,整数)的数组,请使用[value]。
Mark Rajcok '16

40

您可以通过在select标记上创建一个参考变量#device并将其传递到变更处理程序onChange($event, device.value)中,该值应具有新值,从而将该值传递回组件。

<select [(ng-model)]="selectedDevice" #device (change)="onChange($event, device.value)">
    <option *ng-for="#i of devices">{{i}}</option>
</select>

onChange($event, deviceValue) {
    console.log(deviceValue);
}

1
您没有绑定到ngModel这里,而是绑定到了一个名为的新变量device
lux

4
最新的侧倾[(ngModel)]这里
Pardeep耆那

2
@Brocco您和马克的都正确。希望你能理解我只能选择一个答案。:)
苗洪波

22

只需使用[ngValue]而不是[value]!

export class Organisation {
  description: string;
  id: string;
  name: string;
}
export class ScheduleComponent implements OnInit {
  selectedOrg: Organisation;
  orgs: Organisation[] = [];

  constructor(private organisationService: OrganisationService) {}

  get selectedOrgMod() {
    return this.selectedOrg;
  }

  set selectedOrgMod(value) {
    this.selectedOrg = value;
  }
}


<div class="form-group">
      <label for="organisation">Organisation
      <select id="organisation" class="form-control" [(ngModel)]="selectedOrgMod" required>
        <option *ngFor="let org of orgs" [ngValue]="org">{{org.name}}</option>
      </select>
      </label>
</div>

1
这对我有帮助。不知道我的情况是否略有不同,但是对我(change)="selectOrg(selectedOrg)"来说,使用当前/上一个选择而不是新选择的选项调用函数selectOrg。我想通了,我什至不需要(change)一点。
尼克,

好发现。是的,这是(更改)通过旧模型的奇怪行为。我认为这就像ng-change也许是angular2中的错误。我已经更新它以使用get和set方法。这样,在set selectedOrgMod(value)方法中,我可以知道组织已更改并更新了我的组织团队列表。
罗伯特·金

12

我在https://angular.io/docs/ts/latest/guide/forms.html上进行Angular 2表单教程(TypeScript版本)时遇到了这个问题。

select / option块不允许通过选择选项之一来更改选择的值。

尽管我想知道原始教程中是否遗漏了某些东西,或者是否有更新,但是按照Mark Rajcok的建议进行了工作。无论如何,添加

onChange(newVal) {
    this.model.power = newVal;
}

到HeroFormComponent类中的hero-form.component.ts

(change)="onChange($event.target.value)"

<select>元素中的hero-form.component.html 使其起作用


4

在角度6及更高角度中使用selectionChange。例 (selectionChange)= onChange($event.value)


我没有使用反应式方法,我只需要选择值以基于该单个值触发服务调用即可。以上方法对我有帮助。
阿纳瓦拉斯lamurep

3

另一种选择是将对象的值存储为字符串:

<select [ngModel]="selectedDevice | json" (ngModelChange)="onChange($event)">
    <option [value]="i | json" *ngFor="let i of devices">{{i}}</option>
</select>

零件:

onChange(val) {
    this.selectedDevice = JSON.parse(val);
}

这是我可以通过两种方式绑定来设置页面加载时的选择值的唯一方法。这是因为填充选择框的列表与选择框所绑定的对象并不完全相同,并且它必须是相同的对象,而不仅仅是相同的属性值。


3
<mat-form-field>
<mat-select placeholder="Vacancies" [(ngModel)]="vacanciesSpinnerSelectedItem.code" (ngModelChange)="spinnerClick1($event)"
    [ngModelOptions]="{standalone: true}" required>
    <mat-option *ngFor="let spinnerValue of vacanciesSpinnerValues" [value]="spinnerValue?.code">{{spinnerValue.description}}</mat-option>
</mat-select>

我将此用于角度材质下拉列表。工作良好


1

最新的ionic 3.2.0已将(change)修改为(ionChange)

例如:HTML

<ion-select (ionChange)="function($event)"> <ion-option>1<ion-option>
</ion-select>

TS

function($event){
// this gives the selected element
 console.log($event);

}

1

角7/8

从角度6开始,已弃用ngModel输入属性和反应形式指令,在角度7+中将其完全删除。在此处阅读官方文档。

使用反应形式方法,您可以将所选数据获取/设置为;

      //in your template
 <select formControlName="person" (change)="onChange($event)"class="form-control">
    <option [value]="null" disabled>Choose person</option>
      <option *ngFor="let person of persons" [value]="person"> 
        {{person.name}}
    </option>
 </select> 


 //in your ts
 onChange($event) {
    let person = this.peopleForm.get("person").value
    console.log("selected person--->", person);
    // this.peopleForm.get("person").setValue(person.id);
  }

0

Angular 5中,我采用以下方式。获取对象$ event.value而不是$ event.target.value

<mat-form-field color="warn">
   <mat-select (ngModelChange)="onChangeTown($event)" class="form-width" formControlName="branch" [(ngModel)]="branch" placeholder="Enter branch">
     <mat-option *ngFor="let branch of branchs" [value]="branch.value">
                  {{ branch.name }}
     </mat-option>
   </mat-select>
</mat-form-field>

onChangeTown(event): void {
  const selectedTown = event;
  console.log('selectedTown: ', selectedTown);
}

0

在Angular 8中,您可以像这样简单地使用“ selectionChange”:

 <mat-select  [(value)]="selectedData" (selectionChange)="onChange()" >
  <mat-option *ngFor="let i of data" [value]="i.ItemID">
  {{i.ItemName}}
  </mat-option>
 </mat-select>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.