Як я можу отримати новий вибір у "select" у куті 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 нових форм


anwere є правильним, але яка роль ngModel тут m все ще плутаєш, ти поясниш це?
Pardeep Jain

1
@PardeepJain, використовуючи двостороннє зв’язування даних з NgModel, змушує Angular до 1) автоматично оновлюватися, selectedDeviceколи користувач вибирає інший елемент, і 2) якщо ми встановимо значення selectedDevice, NgModel автоматично оновить подання. Оскільки ми також хочемо отримувати сповіщення про зміни, я додав (change)обов'язковість події. Ми не повинні робити це таким чином ... ми повинні мати можливість розірвати двостороння прив'язка даних [ngModel]="selectedDevice" and (ngModelChange)="onChange($event)", але, як я з’ясував, onChange()дзвонять двічі за кожну зміну списку вибору.
Марк Райчкок

гаразд, ніж одне, будь ласка. я хочу отримати значення: <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 template. Якщо замість цього я написав, (ngModelChange)="onChange('abc')"то newValueотримав би рядок abc. Це просто звичайна функція JavaScript.
Марк Райкок

2
@HongboMiao, використовуйте [ngValue], якщо у вас є масив об'єктів. Використовуйте [value], якщо у вас є масив примітивних типів (string, boolean, integer).
Марк Райчко

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.
люкс

4
Whats the roll [(ngModel)]here
Pardeep Jain

2
@Brocco Правильні і ваші, і Маркові. Сподіваюся, ви можете зрозуміти, що я можу вибрати лише одну відповідь. :)
Hongbo Miao

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. Таким чином, у наборі методу selectedOrgMod (value) я можу знати, що організація змінилася та оновила мій список організаційних команд.
Роберт Кінг

12

Я зіткнувся з цією проблемою, роблячи підручник Angular 2 form (версія TypeScript) за адресою https://angular.io/docs/ts/latest/guide/forms.html

Блок select / option не дозволив змінити значення вибору шляхом вибору однієї з опцій.

Робити те, що запропонував Марк Райкок, працював, хоча мені цікаво, чи є щось, що я пропустив в оригінальному підручнику, чи було оновлення. У будь-якому випадку додавання

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

до hero-form.component.ts в класі HeroFormComponent

і

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

to hero-form.component.html в <select>елементі змусило його працювати


4

використовуйте selectChange в кутовій 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

останні іонні 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 ви можете просто використовувати "selectChange" так:

 <mat-select  [(value)]="selectedData" (selectionChange)="onChange()" >
  <mat-option *ngFor="let i of data" [value]="i.ItemID">
  {{i.ItemName}}
  </mat-option>
 </mat-select>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.