2015-10-17 142 views
39

我在創建一個由對象數組支持的Angular2中的選擇而不是字符串時遇到問題。我知道如何在AngularJS中使用ngOptions,但它在Angular2中似乎不起作用(我使用alpha 42)。如何在Angular2中的對象數組上使用select/option/NgFor

在下面的示例中,我有四個選擇,但只有其中兩個工作。

  1. '選擇字符串'是一個簡單的基於字符串的選擇,它工作正常。
  2. '通過雙向綁定選擇對象'是我嘗試使用雙向綁定。不幸的是,它失敗的方式有兩種 - 當頁面加載時,select顯示錯誤的值(foo而不是bar),當我在列表中選擇一個選項時,值'[object Object]'被髮送到後備存儲而不是正確的價值。
  3. '通過事件選擇對象'是我嘗試從$ event中獲取所選值。它也以兩種方式失敗 - 初始加載與#2相同的方式不正確,當我在列表中選擇一個選項時,從事件中檢索值'[object object]',所以我不能獲得正確的價值。選擇被清除。
  4. 'Select Object via string'是唯一使用工作對象的方法。不幸的是,它通過使用#1中的字符串數組並將字符串中的值轉換爲對象並返回,實際上起作用。

我可以做#4如果這是預期的方式,但它似乎很笨重。還有另一種方法嗎?我在阿爾法呢還爲時過早嗎?我做了些傻事嗎?

import {Component, FORM_DIRECTIVES, NgFor} from 'angular2/angular2'; 

interface TestObject { 
    name:string; 
    value:number; 
} 

@Component({ 
    selector: 'app', 
    template: ` 
    <h4>Select String</h4> 
    <select [(ng-model)]="strValue"> 
     <option *ng-for="#o of strArray" [value]="o">{{o}}</option> 
    </select> 

    <h4>Select Object via 2-way binding</h4> 
    <select [(ng-model)]="objValue1"> 
     <option *ng-for="#o of objArray" [value]="o">{{o.name}}</option> 
    </select> 

    <h4>Select Object via event</h4> 
    <select [ng-model]="objValue2" (change)="updateObjValue2($event)"> 
     <option *ng-for="#o of objArray" [value]="o">{{o.name}}</option> 
    </select> 

    <h4>Select Object via string</h4> 
    <select [ng-model]="objValue3.name" (change)="updateObjValue3($event)"> 
     <option *ng-for="#o of strArray" [value]="o">{{o}}</option> 
    </select> 

    <div><button (click)="printValues()">Print Values</button></div> 

    `, 
    directives: [FORM_DIRECTIVES, NgFor] 
}) 
export class AppComponent { 
    objArray:TestObject[] = [{name: 'foo', value: 1}, {name: 'bar', value: 1}]; 
    objValue1:TestObject = this.objArray[1]; 
    objValue2:TestObject = this.objArray[1]; 
    objValue3:TestObject = this.objArray[1]; 

    strArray:string[] = this.objArray.map((obj:TestObject) => obj.name); 
    strValue:string = this.strArray[1]; 

    updateObjValue2(event:Event):void { 
    const value:string = (<HTMLSelectElement>event.srcElement).value; 

    this.objValue2 = this.objArray.find((obj:TestObject) => obj.name === value); 
    } 

    updateObjValue3(event:Event):void { 
    const value:string = (<HTMLSelectElement>event.srcElement).value; 

    this.objValue3 = this.objArray.find((obj:TestObject) => obj.name === value); 
    } 

    printValues():void { 
    console.log('strValue', this.strValue); 
    console.log('objValue1', this.objValue1); 
    console.log('objValue2', this.objValue2); 
    console.log('objValue3', this.objValue3); 
    } 
} 
+5

親愛的時間旅行者來到這裏在2016年或以後! [鏈接的問題](http://stackoverflow.com/q/35945001)有一個[更好的答案](http://stackoverflow.com/a/35945293)它不使用hacky對象到json-對象轉換。 –

+0

是的。然而,奇怪的是,當這個問題比另一個早5個月時,這個問題被標記爲另一個問題的重複。 – user3221325

回答

15

我不是DOM或Javascript/Typescript的專家,但我認爲DOM標籤無法處理真正的JavaScript對象。但是把整個對象作爲一個字符串和解析回的對象/ JSON爲我工作:

interface TestObject { 
    name:string; 
    value:number; 
} 

@Component({ 
    selector: 'app', 
    template: ` 
     <h4>Select Object via 2-way binding</h4> 

     <select [ngModel]="selectedObject | json" (ngModelChange)="updateSelectedValue($event)"> 
     <option *ngFor="#o of objArray" [value]="o | json" >{{o.name}}</option> 
     </select> 

     <h4>You selected:</h4> {{selectedObject }} 
    `, 
    directives: [FORM_DIRECTIVES] 
}) 
export class App { 
    objArray:TestObject[]; 
    selectedObject:TestObject; 
    constructor(){ 
    this.objArray = [{name: 'foo', value: 1}, {name: 'bar', value: 1}]; 
    this.selectedObject = this.objArray[1]; 
    } 
    updateSelectedValue(event:string): void{ 
    this.selectedObject = JSON.parse(event); 
    } 
} 
+2

謝謝。我沒有測試過它,但它看起來會起作用。它仍然不明顯,笨重,所以我希望ng2團隊提出更直接的方法,但這是一個明確的選擇。 – user3221325

+0

感謝您的幫助。我發佈了這個問題(添加你的例子)到問題列表中:https://github.com/angular/angular/issues/4843 – user3221325

+0

順便說一句,與Angular2,事件作爲一個對象進來,所以'updateSelectedValue(event:string )函數需要更改爲'updateSelectedValue(event:Object)',函數的內容需要改爲'this.selectedObject = JSON.parse(event.target.value);' – RHarris

33

我不知道是什麼東西像阿爾法,但我使用測試版12權現在,這工作正常。如果你有對象的數組,創建一個選擇是這樣的:

<select [(ngModel)]="simpleValue"> // value is a string or number 
    <option *ngFor="#obj of objArray" [value]="obj.value">{{obj.name}}</option> 
</select> 

如果要符合實際的對象,我會做這樣的:

<select [(ngModel)]="objValue"> // value is an object 
    <option *ngFor="#obj of objArray" [ngValue]="obj">{{obj.name}}</option> 
</select> 
+10

當用戶在列表中選擇一個項目時,綁定工作會發現。但是,加載頁面時,所選項目無法正確顯示。你能提供一個實例嗎? – AustinTX

+2

無法綁定到'ngModel',因爲它不是'select'的已知屬性。這就是我得到的 – John

+1

您可能需要導入formsModule – carrizal

相關問題