По умолчанию Angular2 <option> в <select> с двусторонней привязкой
Я хотел бы установить <select>
по умолчанию <option>
с помощью HTML и заполнить остальную часть <select>
двумя способами привязки к моей модели.
HTML:
<select class="form-control" required
[(ngModel)]="model.product"
ngControl="product">
<option value="">Select a product</option>
<option *ngFor="#product of products" [value]="product">{{product}}</option>
</select>
Модель:
products: string[] = [
'Foo',
'Bar'
];
Что происходит сейчас, мой выбор является привязкой к модели, которая:
model: Entry = new Entry();
Итак, в свойстве product
нет значения по умолчанию, поэтому <select>
ничего не связывает. Я имею в виду, что это работает так, как ожидалось.
Я пытаюсь выяснить, как получить значение по умолчанию для отображения в <select>
, хотя, и я бы хотел сделать это без жесткого кодирования значения пользовательского интерфейса в моей модели и по умолчанию, что в новом экземпляре моей модели. Имеет ли Angular 2 способ справиться с этим?
Edit:
Результат HTML должен выглядеть так:
<select>
<option value>Select a product</option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
</select>
Ответы
Ответ 1
Я не думаю, что у Angular есть способ справиться с этим. Вам нужно будет выполнить некоторую работу:
<select class="form-control" required [(ngModel)]="model.product">
<option *ngFor="#product of [defaultStr].concat(products)"
[value]="product === defaultStr ? null : product">
{{product}}
</option>
</select>
defaultStr = 'Select a product';
model = { product: null };
products: string[] = [
'Foo',
'Bar'
];
Plunker
Поскольку вы используете NgModel для привязки выбранного значения, вы должны сначала установить свойство bound на значение по умолчанию, которое равно null
, иначе опция не будет выбрана по умолчанию:
model = { product: null };
С null
я заметил, что HTML
<option value="null">Select a product</option>
Итак, вы можете предпочесть использовать пустую строку ''
вместо null
:
[value]="product === defaultStr ? '' : product"
model = { product: '' };
Тогда HTML
<option value="">Select a product</option>
Ответ 2
Я сделал это так и работает для меня:
<select name="Products" #Products="ngModel" [(ngModel)]="products">
<option [ngValue]="products">-- Select product --</option>
<option *ngFor="let p of productsList" [ngValue]="p">{{p.name}}</option>
</select>
Ответ 3
Фактически вы можете создать Directive
, чтобы добавить параметр по умолчанию и обработать двустороннюю привязку:
import {Directive, ElementRef, Input, OnInit, Output, EventEmitter, HostListener} from 'angular2/core';
/**
* <select [ngSelect]="'select number...'" [(ngSelectModel)]="model" >
* <option *ngFor="#item of ['1', '2', '3']" [value]="item">{{item}}</option>
* </select>
*/
@Directive({
selector: '[ngSelect]'
})
export class DefaultOption implements OnInit
{
private _el:HTMLSelectElement;
@Input('ngSelect')
private defaultText:string;
@Output()
private ngSelectModelChange:EventEmitter = new EventEmitter();
private _ngSelectModel:any;
constructor(el:ElementRef)
{
this._el = el.nativeElement;
}
@Input()
public get ngSelectModel():any
{
return this._ngSelectModel;
}
public set ngSelectModel(value:any)
{
this._ngSelectModel = value;
if (this.ngSelectModel !== undefined)
{
this._el.value = this.ngSelectModel;
}
else
{
this._el.value = '';
}
}
protected ngOnInit():any
{
var element:HTMLOptionElement = document.createElement('option');
element.text = this.defaultText;
element.value = '';
this._el.insertBefore(element, this._el.firstChild);
//delayed execution
setTimeout(()=>
{
if (this.ngSelectModel !== undefined)
{
this._el.value = this.ngSelectModel;
}
else
{
this._el.value = '';
}
}, 0);
}
@HostListener('change', ['$event.target.value'])
private onInput(value):void
{
if(value !== '')
{
this.ngSelectModelChange.emit(value);
}
else
{
this.ngSelectModelChange.emit(undefined);
}
}
}
Ответ 4
В бета-версии 14 (см.: Angula2-beta.14 Changlog), angular добавляет поддержку объекта в теги select:
<select class="form-control" required [(ngModel)]="model.product">
<option *ngFor="#prod of products"
[ngValue]="prod">
{{prod.name}}
</option>
</select>
вместо [value]
, вы можете использовать [ngValue]
для привязки объекта к ngModel
в теге select.
Вы можете увидеть пример Plunker со значением по умолчанию.
Атрибут selected
не работает, я пытаюсь исправить это в своем проекте с помощью некоторого обходного пути!
Надеюсь, что это может быть полезно.
Ответ 5
У меня точно такая же проблема, мы можем просто привязать ngModel к значению:
<option *ngFor="#product of products" [value]="model.product">{{product}}</option>
Ответ 6
Вы приближаетесь в правильном направлении. Одна вещь, которая должна учитывать, это то, что значение null модели сравнивается с пустым значением строки по умолчанию.
Поэтому, если вы сравниваете и устанавливаете нулевое значение отображаемого текста по умолчанию, тогда он будет работать нормально.
Я поставил выше, и он работает для меня!
<select class="form-control"
required
[(ngModel)]="model.product"
ngControl="product">
<option value="model.product === null ? null : ''">
Select a product
</option>
<option *ngFor="#product of products"
[value]="product">{{product}}</option>
</select>