Привязка элемента select к объекту в Angular
Я хотел бы привязать элемент 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
будет числом - идентификатором выбранного элемента.
Тем не менее, я бы на самом деле хотел привязать сам объект страны, чтобы selectedValue
был объектом, а не просто идентификатором. Я попытался изменить значение параметра следующим образом:
<option *ngFor="#c of countries" value="c">{{c.name}}</option>
но это не похоже на работу. Кажется, объект помещается в мой selectedValue
, но не тот объект, который я ожидаю. Вы можете увидеть это в моем примере с Plunker.
Я также попытался привязаться к событию изменения, чтобы я мог сам установить объект на основе выбранного идентификатора; однако, похоже, что событие изменения срабатывает до того, как обновляется привязанный ngModel - это означает, что у меня нет доступа к вновь выбранному значению в этот момент.
Есть ли чистый способ привязать выбранный элемент к объекту с Angular 2?
Ответы
Ответ 1
<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
<option *ngFor="let c of countries" [ngValue]="c">{{c.name}}</option>
</select>
Пример StackBlitz
ПРИМЕЧАНИЕ: вы можете использовать [ngValue]="c"
вместо [ngValue]="c.id"
где c - полный объект страны.
[value]="..."
поддерживает только строковые значения
[ngValue]="..."
поддерживает любой тип
Обновить
Если value
является объектом, предварительно выбранный экземпляр должен совпадать с одним из значений.
См. Также недавно добавленное пользовательское сравнение https://github.com/angular/angular/issues/13268, доступное с 4.0.0-beta.7
<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;
}
Ответ 2
Это может помочь:
<select [(ngModel)]="selectedValue">
<option *ngFor="#c of countries" [value]="c.id">{{c.name}}</option>
</select>
Ответ 3
Вы можете сделать это тоже без использования [(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
Ответ 4
Это сработало для меня:
Шаблон 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;
}
Ответ 5
На тот случай, если кто-то хочет сделать то же самое с помощью Reactive Forms:
<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>
Проверьте рабочий пример здесь
Ответ 6
Вы можете выбрать идентификатор, используя функцию
<option *ngFor="#c of countries" (change)="onchange(c.id)">{{c.name}}</option>
Ответ 7
Для меня это работает так, вы можете утешить event.target.value
.
<select (change) = "ChangeValue($event)" (ngModel)="opt">
<option *ngFor=" let opt of titleArr" [value]="opt"></option>
</select>
Ответ 8
Кроме того, если ничего из указанных решений не работает, проверьте, не импортировали ли вы "FormsModule" из "AppModule", это было для меня ключом.
Ответ 9
Вы можете получить выбранное значение также с помощью кнопки 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>
Ответ 10
Создать еще один геттер для выбранного элемента
<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>
В тс:
get selectedCountry(){
let countryId = this.countryForm.controls.country.value;
let selected = this.countries.find(c=> c.id == countryId);
return selected;
}
Ответ 11
используйте этот способ также..
<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
<option *ngFor="let c of countries" value="{{c.id}}">{{c.name}}</option>
</select>
Ответ 12
В 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;
}
}