Bagaimana saya bisa mendapatkan pilihan baru di "pilih" di Angular 2?

372

Saya menggunakan Angular 2 (TypeScript).

Saya ingin melakukan sesuatu dengan pilihan baru, tetapi apa yang saya dapatkan onChange()selalu merupakan pilihan terakhir. Bagaimana saya bisa mendapatkan pilihan baru?

<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.
}
Hongbo Miao
sumber

Jawaban:

751

Jika Anda tidak membutuhkan pengikatan data dua arah:

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

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

Untuk pengikatan data dua arah, pisahkan binding acara dan properti:

<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 ...
}

Jika devicesarray objek, ikat ke ngValuealih-alih 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- tidak menggunakan <form>
Plunker- menggunakan <form>dan menggunakan bentuk API baru

Mark Rajcok
sumber
apakah benar tetapi apa peran ngModel di sini masih bingung apakah Anda akan menjelaskannya?
Pardeep Jain
1
@PardeepJain, menggunakan pengikatan data dua arah dengan NgModel menyebabkan Angular ke 1) secara otomatis memperbarui selectedDeviceketika pengguna memilih item yang berbeda, dan 2) jika kita menetapkan nilai selectedDevice, NgModel akan secara otomatis memperbarui tampilan. Karena kami juga ingin diberitahu tentang perubahan, saya menambahkan (change)acara tersebut mengikat. Kita seharusnya tidak harus melakukannya dengan cara ini ... kita harus dapat memecah data dua arah yang mengikat [ngModel]="selectedDevice" and (ngModelChange)="onChange($event)", tetapi ketika saya tahu, onChange()dipanggil dua kali untuk setiap daftar pilih mengubah cara itu.
Mark Rajcok
oke thanx satu hal lagi tolong. saya ingin mendapatkan nilai: <option *ngFor="#course of course_array #i=index" #newone value={{course.id}} >{{course.course_name}}</option> course.course_namedan course.idkeduanya bagaimana saya bisa mengirim keduanya melalui fungsi (perubahan)?
Pardeep Jain
1
@HongboMiao, $eventvariabel / simbol khusus adalah bagian dari "konteks pernyataan" yang dimiliki oleh pernyataan template Angular. Jika sebaliknya saya menulis (ngModelChange)="onChange('abc')"maka newValueakan mendapatkan string abc. Itu hanya panggilan fungsi JavaScript normal.
Mark Rajcok
2
@HongboMiao, gunakan [ngValue] jika Anda memiliki array objek. Gunakan [nilai] jika Anda memiliki array tipe primitif (string, boolean, integer).
Mark Rajcok
40

Anda dapat meneruskan nilai kembali ke komponen dengan membuat variabel referensi pada tag pilih #devicedan meneruskannya ke penangan perubahan onChange($event, device.value)harus memiliki nilai baru

<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);
}
Brocco
sumber
1
Anda tidak mengikat di ngModelsini, Anda mengikat ke variabel baru yang disebut device.
lux
4
whats the roll of [(ngModel)]here
Pardeep Jain
2
@Brocco Anda dan Markus benar. Semoga Anda bisa mengerti saya hanya bisa memilih satu jawaban. :)
Hongbo Miao
22

Cukup gunakan [ngValue] alih-alih [nilai] !!

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>
raja robert
sumber
1
Ini membantu saya. Tidak yakin apakah kasus saya sedikit berbeda, tetapi bagi saya (change)="selectOrg(selectedOrg)"memanggil fungsi selectOrg dengan pilihan saat ini / sebelumnya, bukan pilihan yang baru dipilih. Saya menemukan, saya bahkan tidak membutuhkannya (change).
Nick
Tempat yang bagus. ya itu perilaku aneh dengan (perubahan) melewati model lama. Saya pikir itu akan seperti ng-ubah mungkin itu bug di angular2. Saya telah memperbaruinya untuk menggunakan metode get dan set. Dengan cara itu dalam set yang dipilih, metode OrgMod (nilai) saya bisa tahu bahwa organisasi telah berubah dan memperbarui daftar tim organisasi saya.
robert king
12

Saya mengalami masalah ini saat melakukan tutorial Angular 2 form (versi TypeScript) di https://angular.io/docs/ts/latest/guide/forms.html

Blok pilih / opsi tidak memungkinkan nilai seleksi diubah dengan memilih salah satu opsi.

Melakukan apa yang disarankan Mark Rajcok berhasil, meskipun saya bertanya-tanya apakah ada sesuatu yang saya lewatkan dalam tutorial asli atau jika ada pembaruan. Bagaimanapun, menambahkan

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

ke hero-form.component.ts di kelas HeroFormComponent

dan

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

to hero-form.component.html pada <select>elemen yang membuatnya berfungsi

Jarisky
sumber
4

gunakan selectionChange di sudut 6 dan di atas. contoh (selectionChange)= onChange($event.value)

valentine
sumber
Saya tidak menggunakan pendekatan formulir reaktif. Saya hanya perlu nilai yang dipilih untuk memicu panggilan layanan berdasarkan nilai tunggal itu .. metode di atas membantu saya.
anavaras lamurep
3

Pilihan lain adalah menyimpan objek dalam nilai sebagai string:

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

komponen:

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

Ini adalah satu-satunya cara saya bisa mendapatkan dua cara mengikat untuk mengatur nilai pilih pada pemuatan halaman. Ini karena daftar saya yang mengisi kotak pilih bukan objek yang sama persis seperti yang saya pilih terikat dan perlu objek yang sama, bukan hanya nilai properti yang sama.

kravits88
sumber
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>

Saya menggunakan ini untuk dropdown Material sudut. bekerja dengan baik

Apurv
sumber
1

ionic 3.2.0 terbaru telah dimodifikasi (ubah) menjadi (ionChange)

misal: HTML

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

TS

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

}
selip
sumber
1

7/8 sudut

Pada sudut 6, penggunaan properti input ngModel dengan arahan bentuk reaktif telah ditinggalkan dan dihapus sama sekali dalam sudut 7+. Baca dokumen resmi di sini.

Menggunakan pendekatan formulir reaktif Anda dapat / mengatur data yang dipilih sebagai;

      //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);
  }
7guyo
sumber
0

Di Angular 5 saya lakukan dengan cara berikut. dapatkan objek $ event.value alih-alih $ 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);
}
Kumaresan Perumal
sumber
0

Di Angular 8 Anda cukup menggunakan "selectionChange" seperti ini:

 <mat-select  [(value)]="selectedData" (selectionChange)="onChange()" >
  <mat-option *ngFor="let i of data" [value]="i.ItemID">
  {{i.ItemName}}
  </mat-option>
 </mat-select>
B. Habibzadeh
sumber