선택 요소를 각도로 객체에 바인딩


409

select 요소를 객체 목록에 바인딩하고 싶습니다.

@Component({
   selector: 'myApp',
   template: `<h1>My Application</h1>
              <select [(ngModel)]="selectedValue">
                 <option *ngFor="#c of countries" value="c.id">{{c.name}}</option>
              </select>`
})
export class AppComponent{
    countries = [
       {id: 1, name: "United States"},
       {id: 2, name: "Australia"}
       {id: 3, name: "Canada"},
       {id: 4, name: "Brazil"},
       {id: 5, name: "England"}
     ];
    selectedValue = null;
}

이 경우 selectedValue선택한 항목의 ID 인 숫자로 나타납니다 .

그러나 실제로 국가 개체 자체에 바인딩 selectedValue하여 ID가 ​​아닌 개체가되도록하고 싶습니다 . 옵션 값을 다음과 같이 변경하려고했습니다.

<option *ngFor="#c of countries" value="c">{{c.name}}</option>

그러나 이것은 작동하지 않는 것 같습니다. 내 물건을 놓는 것처럼 보이지만 selectedValue내가 기대하는 물건은 아닙니다. 내 Plunker 예제에서 이것을 볼 수 있습니다 .

또한 선택된 id를 기반으로 객체를 직접 설정할 수 있도록 change 이벤트에 바인딩을 시도했습니다. 그러나 바인딩 된 ngModel이 업데이트되기 전에 변경 이벤트가 발생하는 것으로 보입니다. 즉, 해당 시점에서 새로 선택한 값에 액세스 할 수 없습니다.

선택 요소를 Angular 2를 사용하여 객체에 바인딩하는 명확한 방법이 있습니까?


Plunk는 IE와 Chrome에서 조금 다르게 작동한다는 것을 알았습니다. 어느 쪽도 실제로 내가 원하는 방식으로 작동하지는 않지만 참고로합니다.
RHarris

답변:


734
<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
  <option *ngFor="let c of countries" [ngValue]="c">{{c.name}}</option>
</select>

StackBlitz 예제

참고 : c가 완전한 국가 개체 인 경우 [ngValue]="c"대신 사용할 수 있습니다 [ngValue]="c.id".

[value]="..."문자열 값만
[ngValue]="..."지원 모든 유형을 지원

최신 정보

(가)하면 value객체가 상기 사전 선택된 인스턴스의 값 중 하나와 동일 할 필요가있다.

4.0.0-beta.7부터 사용 가능한 최근에 추가 된 사용자 지정 비교 https://github.com/angular/angular/issues/13268 참조

<select [compareWith]="compareFn" ...

액세스를 원하는 경우의주의 this내에서 compareFn.

compareFn = this._compareFn.bind(this);

// or 
// compareFn = (a, b) => this._compareFn(a, b);

_compareFn(a, b) {
   // Handle compare logic (eg check if unique ids are the same)
   return a.id === b.id;
}

21
그것을 시도했지만 이것은 드롭 다운에서 모델로만 데이터 바인딩되는 것처럼 보입니다. 모델이 이미 설정된 페이지로 들어가면 드롭 다운이 적절하게 설정되지 않습니다.
Strinder

13
@Strinder 빈번한 실수는 of (기본 항목) selectedValue이외의 다른 객체 인스턴스를 사용하는 것입니다 c. 동일한 속성과 값을 가진 다른 객체가 작동하지 않으면 동일한 객체 인스턴스 여야합니다.
Günter Zöchbauer

1
@ GünterZöchbauer 네. 이미 생각했다. 따라서 모델 및 값 목록과 직접 동기화하는 쉬운 방법이 없습니까? = 항상 onChange를 통해?
Strinder

1
곧 우리는 ngModel 객체를 커스텀 비교기 함수를 사용하여 속성별로 비교할 수 있습니다. 다만이 문제를보고 : github.com/angular/angular/issues/13268
kub1x

1
;-) 일단 알면 항상 쉽지만 angular.io/api/forms/NgSelectOption#description 에는 angular.io/api/forms/SelectControlValueAccessor 링크가 포함되어 있습니다 .
Günter Zöchbauer

41

이것은 도움이 될 수 있습니다.

    <select [(ngModel)]="selectedValue">
          <option *ngFor="#c of countries" [value]="c.id">{{c.name}}</option>
    </select>

5
[ngValue] 대신 [value]를 사용했습니다. 이건 같은게 아니야. 이것은 나를 위해 일했다
Carolina Faedo

2
각도 4
sea-kg

2
@ sea-kg let대신 사용#
Ashraful Islam

1
이 답변은 선택된 값을 얻지
못함

20

당신도 사용할 필요없이이 작업을 수행 할 수 있습니다 [(ngModel)]귀하의 <select>태그

ts 파일에 변수를 선언하십시오.

toStr = JSON.stringify;

그리고 당신 템플릿에서 이것을하십시오.

 <option *ngFor="let v of values;" [value]="toStr(v)">
      {{v}}
 </option>

그런 다음 사용

let value=JSON.parse(event.target.value)

문자열을 유효한 JavaScript 객체로 다시 구문 분석


1
이것은 실제로 가능하지만 큰 물체에서는 고통이 될 것입니다. 또한 Angular의 변경 감지 기능에 대한 밑줄 기능도 고려해야합니다. 봇이 쉽게 파싱 할 수있는 정보를 json으로 출력하면 성능이 저하됩니다. Angular의 변경 감지를 사용하면 데이터의 논리를 숨기고 (캡슐화) 필요한 정보를 얻을 수 있습니다. @ Günter Zöchbauer의 대답은 Angular에서 수행하는 방법입니다. :)
Lucaci Andrei

단일 목록이 있고 하나의 값을 변경하면 다음 값을 업데이트해서는 안되므로 ngmodel을 사용하지 않고 이것을 해킹으로 사용하는 데 도움이되었습니다. 감사합니다 :)
Melvin

이것은 일반 JavaScript 객체에서 작동하지만 클래스의 인스턴스에서는 모든 메소드가 손실됩니다.
KhalilRavanna

13

그것은 나를 위해 일했다 :

템플릿 HTML :

에 추가 (ngModelChange)="selectChange($event)"했습니다 select.

<div>
  <label for="myListOptions">My List Options</label>
  <select (ngModelChange)="selectChange($event)" [(ngModel)]=model.myListOptions.id >
    <option *ngFor="let oneOption of listOptions" [ngValue]="oneOption.id">{{oneOption.name}}</option>
  </select>
</div>

component.ts에서 :

  listOptions = [
    { id: 0, name: "Perfect" },
    { id: 1, name: "Low" },
    { id: 2, name: "Minor" },
    { id: 3, name: "High" },
  ];

component.ts이 기능에 추가해야 합니다.

  selectChange( $event) {
    //In my case $event come with a id value
    this.model.myListOptions = this.listOptions[$event];
  }

참고 : 나는 노력 [select]="oneOption.id==model.myListOptions.id"하고 작동하지 않습니다.

============= 다른 방법은 다음과 같습니다. =========

템플릿 HTML :

에 추가 [compareWith]="compareByOptionId했습니다 select.

<div>
  <label for="myListOptions">My List Options</label>
  <select [(ngModel)]=model.myListOptions [compareWith]="compareByOptionId">
    <option *ngFor="let oneOption of listOptions" [ngValue]="oneOption">{{oneOption.name}}</option>
  </select>
</div>

component.ts에서 :

  listOptions = [
    { id: 0, name: "Perfect" },
    { id: 1, name: "Low" },
    { id: 2, name: "Minor" },
    { id: 3, name: "High" },
  ];

component.ts이 기능에 추가해야 합니다.

 /* Return true or false if it is the selected */
 compareByOptionId(idFist, idSecond) {
    return idFist && idSecond && idFist.id == idSecond.id;
 }

변경 이벤트를 처리하여 추가 작업을 수행하려는 경우에 유용합니다 (예 : 변경 콜백 알림). 이 경우에 [ngModel]정의 된 사용자 지정 변경 콜백에 모델을 수동으로 배치 한 다음 설정하기 만하면됩니다 (ngModelChange).
호감

9

누군가가 반응성 양식을 사용하여 동일한 작업을 수행하려는 경우를 대비하여 :

<form [formGroup]="form">
  <select formControlName="country">
    <option *ngFor="let country of countries" [ngValue]="country">{{country.name}}</option>
  </select>
  <p>Selected Country: {{country?.name}}</p>
</form>

작업 예제를 확인 하십시오.


5

기능을 사용하여 ID를 선택할 수 있습니다

<option *ngFor="#c of countries" (change)="onchange(c.id)">{{c.name}}</option>

4

나를 위해 이런 식으로 작동하면 콘솔 할 수 있습니다 event.target.value.

<select (change) = "ChangeValue($event)" (ngModel)="opt">   
    <option *ngFor=" let opt of titleArr" [value]="opt"></option>
</select>

2

또한 주어진 솔루션의 다른 방법으로도 작동하지 않으면 "AppModule"내부에 "FormsModule"을 가져 왔는지 확인하십시오.


2

선택한 항목에 대해 다른 게터 생성

<form [formGroup]="countryForm">
  <select formControlName="country">
    <option *ngFor="let c of countries" [value]="c.id">{{c.name}}</option>
  </select>

  <p>Selected Country: {{selectedCountry?.name}}</p>
</form>

ts에서 :

get selectedCountry(){
  let countryId = this.countryForm.controls.country.value;
  let selected = this.countries.find(c=> c.id == countryId);
  return selected;
}

1

선택한 값을 함수를 통해 전달하여 click ()을 사용하여 선택한 값을 얻을 수도 있습니다.

<md-select placeholder="Select Categorie"  
    name="Select Categorie" >
  <md-option *ngFor="let list of categ" [value]="list.value" (click)="sub_cat(list.category_id)" >
    {{ list.category }}
  </md-option>
</md-select>

0

이 방법도 사용하십시오 ..

<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
     <option *ngFor="let c of countries" value="{{c.id}}">{{c.name}}</option>
 </select>

0

에서 app.component.html:

 <select type="number" [(ngModel)]="selectedLevel">
          <option *ngFor="let level of levels" [ngValue]="level">{{level.name}}</option>
        </select>

그리고 app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  levelNum:number;
  levels:Array<Object> = [
      {num: 0, name: "AA"},
      {num: 1, name: "BB"}
  ];

  toNumber(){
    this.levelNum = +this.levelNum;
    console.log(this.levelNum);
  }

  selectedLevel = this.levels[0];

  selectedLevelCustomCompare = {num: 1, name: "BB"}

  compareFn(a, b) {
    console.log(a, b, a && b && a.num == b.num);
    return a && b && a.num == b.num;
  }
}

0

<select name="typeFather"
    [(ngModel)]="type.typeFather">
        <option *ngFor="let type of types" [ngValue]="type">{{type.title}}</option>
</select>

이 방법은 항상 작동하지만 동적 목록이 있으면 모델 보다 먼저로드 해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.