Как я могу получить новый выбор в "выберите" в Angular 2?
Я использую 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.
}
15 ответов
Если вам не нужна двусторонняя привязка данных:
<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 ...
}
}
Плункер - не использует <form>
Плункер - использует <form>
и использует новый API форм
Вы можете передать значение обратно в компонент, создав ссылочную переменную в теге 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);
}
Просто используйте [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>
Я столкнулся с этой проблемой при выполнении учебного курса по Angular 2 (версия для TypeScript) по адресу https://angular.io/docs/ts/latest/guide/forms.html
Блок выбора / опции не позволял изменить значение выбора, выбрав один из вариантов.
Делать то, что предложил Марк Райкок, сработало, хотя мне интересно, есть ли что-то, что я пропустил в оригинальном уроке или было обновление. В любом случае добавление
onChange(newVal) {
this.model.power = newVal;
}
на hero-form.component.ts в классе HeroFormComponent
а также
(change)="onChange($event.target.value)"
в hero-form.component.html в <select>
элемент заставил это работать
У меня была такая же проблема, и я решил, используя приведенный ниже код:
(change)="onChange($event.target.value)"
Используйте selectionChange в угловых 6 и выше. пример (selectionChange)= onChange($event.value)
В 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>
Если вам не нужна двусторонняя привязка данных:
<select (change)="updateSorting($event)">
<option disabled selected>Sorting</option>
<option value="pointDes">pointDes</option>
<option value="timeDes">timeDes</option>
<option value="timeAsc">timeAsc</option>
<option value="pointAsc">pointAsc</option>
</select>
updateSorting(e: any) {
// console.log((e.target as HTMLSelectElement)?.value); // also work
console.log(e.target.value);
}
Другой вариант - сохранить объект в значении в виде строки:
<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);
}
Это был единственный способ получить двухстороннюю привязку, чтобы установить значение select при загрузке страницы. Это произошло потому, что мой список, который заполняет поле выбора, не был точно таким же объектом, с которым был связан мой выбор, и он должен быть тем же объектом, а не просто значениями свойств.
Угловой 7/8
Начиная с angular 6, использование свойства ввода ngModel с директивой реактивных форм устарело и полностью удалено в angular 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);
}
<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>
Я использовал это для раскрытия углового материала. работает отлично
Последние ионные 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);
}
Я перепробовал все предложения, и у меня ничего не работает.
Представьте себе ситуацию: вам нужна двусторонняя привязка, и у вас есть поиск со значениями ЧИСЛО, и вы хотите заполнить свой SELECT значениями из этого поиска и выделить выбранный вариант.
Использование [value] или (ngModelChange) недопустимо, потому что вы не сможете выбрать выбранный вариант после того, как пользователь инициировал изменение: [value] считает все строкой, что касается (ngModelChange) - очевидно, не должно использоваться, когда пользователь инициирует изменение, поэтому он нарушает правильный выбор. Использование [ngModel] гарантирует фиксированный формат полученного ЗНАЧЕНИЯ как ИНДЕКС: ЗНАЧЕНИЕ и его легко анализировать соответственно, ОДНАКО еще раз - это портит выбранный вариант.
Итак, мы используем [ngValue] (который позаботится о правильных типах), (change) и... [value], что гарантирует, что обработчик получит VALUE, а не DISPLAYED VALUE или INDEX: VALUE:) Ниже мой рабочий неуклюжий решение:
<select
class="browser-default custom-select"
(change)="onEdit($event.target.value)"
>
<option [value]="">{{
'::Licences:SelectLicence' | abpLocalization
}}</option>
<ng-container *ngIf="licencesLookupData$ | async">
<option
*ngFor="let l of licencesLookupData$ | async"
[ngValue]="l.id"
[value]="l.id"
[selected]="l.id == selected.id"
>
{{ l.id }} {{ l.displayName | defaultValue }}
</option>
</ng-container>
</select>
onEdit(idString: string) {
const id = Number(idString);
if (isNaN(id)) {
this.onAdd();
return;
}
this.licencesLoading = true;
this.licencesService
.getById(id)
.pipe(finalize(() => (this.licencesLoading = false)), takeUntil(this.destroy))
.subscribe((state: Licences.LicenceWithFlatProperties) => {
this.selected = state;
this.buildForm();
this.get();
});
}
Начиная с angular 7 и выше, поскольку ngModel устарел, мы можем просто использовать элемент управления, чтобы очень легко получить новое выбранное значение реактивным способом.
Пример:
<form [formGroup]="frmMyForm">
<select class="form-control" formControlName="fieldCtrl">
<option value=""></option>
<option value="val1">label val 1</option>
<option value="val2">label val 2</option>
<option value="val3">label val 3</option>
</select>
</form>
this.frmMyForm.get('fieldCtrl').valueChanges.subscribe( value => {
this.selectedValue = value;
});
Используя этот полностью реактивный способ, мы можем легко обновить старую версию приложения angular до более новой.
В Angular 5 я поступил следующим образом. получить объект $event.value вместо $event.target.value
<mat-form-field color="warn">
<mat-select 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.value;
console.log('selectedTown: ', selectedTown);
}