2015-10-17 11 views
39

文字列の代わりにオブジェクトの配列を使用するAngular2でselectを作成する際に問題があります。私はngOptionsを使ってAngularJSでそれを行う方法を知っていましたが、Angular2では動作していないようです(私はアルファ42を使用しています)。Angular2のオブジェクトの配列でselect/option/NgForを使用する方法

以下のサンプルでは、​​4つの選択肢がありますが、2つしか選択できません。

  1. 'Select String'は単純な文字列ベースの選択で、正常に動作します。
  2. 2方向バインディングを使用してオブジェクトを選択しようとしましたが、2方向バインディングを使用しようとしました。残念ながら、それは2つの方法で失敗します - ページが読み込まれるとき、selectは間違った値(barの代わりにfoo)を表示し、リスト内のオプションを選択すると、 '[object Object]'という値がバッキングストアに送られます正しい値の代わりに。
  3. 'イベント経由でオブジェクトを選択する'は、$ eventから選択した値を取得しようとしました。それは2つの方法でも失敗します - 最初の読み込みは#2と同じ方法で間違っています。リスト内のオプションを選択すると '[object Object]'という値がイベントから取得されるため、正しい値を得てください。選択がクリアされます。
  4. 'Select Object via string'は、動作するオブジェクトを使用する唯一のアプローチです。残念ながら、#1の文字列配列を使用してstringからobjectへ、そしてbackから値を変換することで実際に動作します。

これは意図した方法であれば#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)には、ハッキングされたオブジェクトツーJson-to-Jsonを使用しない[もっと良い答え](http://stackoverflow.com/a/35945293)オブジェクト変換。 –

+0

真。しかし、この質問がもう1ヶ月前に5ヶ月前に起きたときに、これがもう一方の重複としてマークされたのは変です。 – user3221325

答えて

15

私はDOMやJavascript/Typescriptの専門家ではありませんが、実際のjavascriptオブジェクトは何とか処理できません。私はアルファのように何であったかの事を知らない

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

ありがとうございます。私はそれをテストしていないが、それは動作するように見えます。それはまだ明らかではないし、clunkyなので、ng2チームがもっと直接的なアプローチを思いつくことを願っていますが、それは明確な選択肢です。 – user3221325

+0

ご協力いただきありがとうございます。私は問題リストにこの質問を投稿しました(https://github.com/angular/angular/issues/4843 – user3221325

+0

)。Angular2のBTWはオブジェクトとして入ってくるので、 'updateSelectedValue(event:string ) '関数を' updateSelectedValue(event:Object) 'に変更する必要があり、関数の要点を' this.selectedObject = JSON.parse(event.target.value);に変更する必要があります – RHarris

33

が、私は12権利をベータ版を使用しています。しかし、文字列として全体のオブジェクトを置くと、オブジェクトに戻ってそれを解析/ JSONは私のために働きました今これはうまく動作します。あなたがオブジェクトの配列を持っている場合は、このような選択を作成します:

<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

関連する問題