Angular 2의 "select"에서 새로운 선택을 얻으려면 어떻게해야합니까?


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) 값을 설정하면 selectedDeviceNgModel이 자동으로 뷰를 업데이트합니다. 또한 변경 사항을 알리고 싶기 때문에 (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
특수 $event변수 / 기호 인 @HongboMiao 는 Angular 템플릿 문에있는 "문맥 컨텍스트"의 일부입니다. 대신 내가 쓴 (ngModelChange)="onChange('abc')"다면 newValue문자열을 얻을 것 abc입니다. 정상적인 JavaScript 함수 호출입니다.
Mark Rajcok

2
@HongboMiao, 객체 배열이 있으면 [ngValue]를 사용하십시오. 기본 유형의 배열 (문자열, 부울, 정수)이있는 경우 [value]를 사용하십시오.
마크 Rajcok

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)]여기 롤
무엇입니까

2
@Brocco 당신과 마크 모두 맞습니다. 하나의 답변 만 선택할 수 있음을 이해하기를 바랍니다. :)
Hongbo Miao

22

[value] 대신 [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)"새로 선택한 옵션이 아니라 현재 / 이전 선택으로 함수 selectOrg를 호출합니다. 나는 알아, 심지어 (change)조금 필요하지 않습니다 .
Nick

좋은 스포팅. 예, 이전 모델을 (변경) 통과하는 이상한 행동입니다. ng-change가 angular2의 버그 일 것이라고 생각했습니다. get 및 set 메소드를 사용하도록 업데이트했습니다. 이렇게하면 set selectedOrgMod (value) 메소드에서 조직이 조직 팀 목록을 변경하고 업데이트했음을 알 수 있습니다.
로버트 킹

12

https://angular.io/docs/ts/latest/guide/forms.html 에서 Angular 2 양식 자습서 (TypeScript 버전)를 수행하는 동안이 문제가 발생했습니다.

선택 / 옵션 블록에서 옵션 중 하나를 선택하여 선택 값을 변경할 수 없습니다.

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)


반응 형 접근 방식을 사용하지 않았습니다. 단일 값을 기반으로 서비스 요청을 트리거하기 위해 선택한 값이 필요합니다 .. 위의 방법이 도움이되었습니다.
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

최신 이온 3.2.0이 (ion)을 (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.target.value 대신 $ event.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.