2016-04-14 11 views
20

我想設置一個<select>具有默認<option>使用HTML,並填充<select>的休息與雙向綁定到我的模型違約的Angular2 在<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>雖然,我想這樣做沒有硬編碼我的模型中的UI值,並默認在一個新的實例我的模型。 Angular 2有辦法解決這個問題嗎?

編輯:

結果HTML應該是這樣的:

<select> 
    <option value>Select a product</option> 
    <option value="foo">Foo</option> 
    <option value="bar">Bar</option> 
</select> 
+0

的可能的複製[如何顯示在角2選擇控制佔位符(空的選項)?](https://stackoverflow.com/questions/38725365/how-to-show-placeholder-empty-option -in-select-control-in-angular-2) – djeikyb

回答

13

我不認爲角有辦法解決這個問題。你必須做一些工作:

<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到選定值綁定,你必須設置綁定屬性爲默認值最初,這是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

既然Angular 2.2.1:''是可能的。 https://github.com/angular/angular/commit/e0ce545 –

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

這是一個非常優雅的解決方案,我試着讓它工作;不過,由於Angular的雙向綁定模式,我不認爲它可以工作。你可以用這個注入一個新項目到'