ฉันจะรับตัวเลือกใหม่ใน "เลือก" ใน 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.
}

คำตอบ:


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

โอเคขอบคุณอีกอย่างหนึ่ง ฉันต้องการได้รับค่าของ: <option *ngFor="#course of course_array #i=index" #newone value={{course.id}} >{{course.course_name}}</option> course.course_nameและcourse.idทั้งสองฉันจะส่งทั้งสองผ่านฟังก์ชั่น (เปลี่ยน)?
Pardeep Jain

1
@HongboMiao $eventตัวแปร / สัญลักษณ์พิเศษเป็นส่วนหนึ่งของ "บริบทคำสั่ง" ที่คำสั่งเทมเพลตของ Angular มี แต่ถ้าผมเขียน(ngModelChange)="onChange('abc')"แล้วจะได้รับสตริงnewValue abcเป็นเพียงการเรียกใช้ฟังก์ชัน JavaScript ปกติ
Mark Rajcok

2
@HongboMiao ใช้ [ngValue] ถ้าคุณมีอาร์เรย์ของวัตถุ ใช้ [value] หากคุณมีอาร์เรย์ประเภทดั้งเดิม (สตริงบูลีน, จำนวนเต็ม)
Mark Rajcok

40

คุณสามารถส่งค่ากลับเข้าไปในองค์ประกอบโดยการสร้างตัวแปรอ้างอิงบนแท็กเลือก#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 ทั้งของคุณและของ Mark นั้นถูกต้อง หวังว่าคุณจะเข้าใจฉันสามารถเลือกได้เพียงหนึ่งคำตอบ :)
Hongbo Miao

22

เพียงแค่ใช้ [ngValue] แทน [ค่า] !!

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)"เรียกใช้ฟังก์ชัน select ด้วยการเลือกปัจจุบัน / ก่อนหน้าไม่ใช่ตัวเลือกที่เลือกใหม่ ฉันคิดออกฉันไม่ต้องการแม้แต่(change)นิดเดียว
Nick

จำได้ดี ใช่ว่าเป็นพฤติกรรมแปลก ๆ ที่มี (เปลี่ยน) ผ่านรุ่นเก่า ฉันคิดว่ามันจะเหมือนกับ ng-change บางทีนั่นอาจเป็นข้อผิดพลาดใน angular2 ฉันได้อัปเดตให้ใช้วิธีรับและตั้งค่า ด้วยวิธีดังกล่าวในวิธีการเลือก setOrgMod (ค่า) ฉันสามารถรู้ได้ว่าองค์กรมีการเปลี่ยนแปลงและอัปเดตรายชื่อทีมองค์กรของฉัน
เบิร์ตกษัตริย์

12

ฉันพบปัญหานี้ในขณะที่ทำการสอนแบบฟอร์ม Angular 2 (เวอร์ชัน TypeScript) ที่ https://angular.io/docs/ts/latest/guide/forms.html

บล็อกการเลือก / ตัวเลือกไม่อนุญาตให้เปลี่ยนค่าของการเลือกโดยการเลือกหนึ่งในตัวเลือก

ทำในสิ่งที่ Mark Rajcok แนะนำให้ใช้งานแม้ว่าฉันจะสงสัยว่ามีบางสิ่งที่ฉันพลาดในการสอนดั้งเดิมหรือหากมีการอัปเดต ในกรณีใด ๆ เพิ่ม

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

ถึง hero-form.component.ts ในคลาส HeroFormComponent

และ

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

เพื่อ hero-form.component.html ใน<select>องค์ประกอบทำให้การทำงาน


4

ใช้ selectionChange ในมุม 6 ขึ้นไป ตัวอย่าง (selectionChange)= onChange($event.value)


ฉันไม่ได้ใช้วิธีแบบฟอร์มที่ตอบสนองฉันแค่ต้องการค่าที่เลือกไว้เพื่อทริกเกอร์การให้บริการตามค่าเดียวนั้น .. วิธีการด้านบนช่วยฉันได้
Anavaras 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 ได้แก้ไข (เปลี่ยน) เป็น (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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.