Как я могу получить новый выбор в «select» в Angular 2?

130

Я использую 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 for new selectedDevice, but what I
    // got here is always last selection, not the one I just select.
}
Теги:
angular

6 ответов

300
Лучший ответ

Если вам не нужна двусторонняя привязка данных:

<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 форм

  • 0
    anwere прав, но какова здесь роль ngModel, я все еще не уверен, объясните ли вы это?
  • 0
    @PardeepJain, использование двусторонней привязки данных с NgModel приводит к тому, что Angular 1) автоматически обновляет selectedDevice когда пользователь выбирает другой элемент, и 2) если мы устанавливаем значение selectedDevice , NgModel автоматически обновляет представление. Поскольку мы также хотим получать уведомления об изменении, я добавил (change) привязку события. Мы не должны делать это таким образом ... мы должны иметь возможность разбить двустороннее связывание данных на [ngModel]="selectedDevice" and (ngModelChange)="onChange($event)" , но как я выяснилось, что onChange() дважды для каждого изменения списка выбора таким образом.
Показать ещё 18 комментариев
21

Вы можете передать значение обратно в компонент, создав ссылочную переменную в теге 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 .
  • 3
    что тут происходит [(ngModel)]
Показать ещё 1 комментарий
13

Просто используйте [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) .
  • 0
    Хороший споттинг. да, это странное поведение с (изменением) прохождения старой модели. Я думал, что это будет похоже на ng-change, может быть, это ошибка в angular2. Я обновил его, чтобы использовать методы get и set. Таким образом, в методе set selectedOrgMod (value) я могу знать, что организация изменилась, и обновить мой список организационных команд.
9

Я столкнулся с этой проблемой, выполняя Angular 2 формы учебника (TypeScript версия) на https://angular.io/docs/ts/latest/guide/forms.html

Блок select/option не позволяет изменять значение выбора, выбирая одну из опций.

Выполнение того, что предложил Марк Райкок, хотя мне интересно, есть ли что-то, что я пропустил в оригинальном учебнике, или если было обновление. В любом случае добавление

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

to hero-form.component.ts в классе HeroFormComponent

и

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

to hero-form.component.html в элементе <select> заставил его работать

2

Другой вариант - сохранить объект в виде строки:

<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);
}

Это был единственный способ заставить двухстороннюю привязку работать, чтобы установить значение выбора при загрузке страницы. Это связано с тем, что мой список, который заполняет поле выбора, не является тем же самым объектом, к которому привязан мой выбор, и должен быть тот же объект, а не те же значения свойств.

  • 0
    у вас есть рабочий пример?
0

последние ионные 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);

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню