2015-10-17 26 views
39

Tôi gặp sự cố khi tạo một lựa chọn trong Angular2 được hỗ trợ bởi một mảng đối tượng thay vì chuỗi. Tôi biết làm thế nào để làm điều đó trong AngularJS sử dụng ngOptions, nhưng nó không có vẻ làm việc trong Angular2 (Tôi đang sử dụng alpha 42).Cách sử dụng select/option/NgFor trên một mảng đối tượng trong Angular2

Trong ví dụ bên dưới, tôi có bốn lựa chọn, nhưng chỉ có hai lựa chọn.

  1. 'Chọn chuỗi' là lựa chọn dựa trên chuỗi đơn giản và nó hoạt động tốt.
  2. 'Chọn đối tượng qua liên kết 2 chiều' là nỗ lực của tôi để sử dụng liên kết 2 chiều. Thật không may, nó thất bại theo hai cách - khi tải trang, lựa chọn cho thấy giá trị sai (foo thay vì thanh), và khi tôi chọn một tùy chọn trong danh sách, giá trị '[object Object]' sẽ được gửi đến cửa hàng sao lưu thay vì giá trị chính xác.
  3. 'Chọn Đối tượng qua sự kiện' là nỗ lực của tôi để nhận giá trị đã chọn từ $ event. Nó cũng không thành công theo hai cách - tải ban đầu không đúng theo cách giống như # 2 và khi tôi chọn một tùy chọn trong danh sách, giá trị '[object Object]' được lấy từ sự kiện, vì vậy tôi không thể có được giá trị đúng. Lựa chọn sẽ bị xóa.
  4. 'Chọn đối tượng qua chuỗi' là cách tiếp cận duy nhất sử dụng đối tượng hoạt động. Thật không may, nó thực sự hoạt động bằng cách sử dụng mảng chuỗi từ # 1 và chuyển đổi giá trị từ chuỗi thành đối tượng và ngược lại.

Tôi có thể làm # 4 nếu đó là cách dự định, nhưng có vẻ như khá khó khăn. Có cách tiếp cận nào khác không? Tôi chỉ là quá sớm trong alpha? Tôi đã làm điều gì đó ngớ ngẩn?

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

du khách thời gian thân mến đến đây vào năm 2016 hoặc muộn hơn! [Câu hỏi được liên kết] (http://stackoverflow.com/q/35945001) có [câu trả lời hay hơn] (http://stackoverflow.com/a/35945293) không sử dụng đối tượng hack-to-json-to- chuyển đổi đối tượng. –

+0

Đúng. Thật kỳ lạ, mặc dù, điều này đã được đánh dấu là một bản sao của một trong những khác khi câu hỏi này predated khác một 5 tháng. – user3221325

Trả lời

15

Tôi không có chuyên gia với DOM hoặc Javascript/Typescript nhưng tôi nghĩ rằng thẻ DOM không thể xử lý đối tượng javascript thực bằng cách nào đó. Nhưng đặt toàn bộ đối tượng vào dưới dạng một chuỗi và phân tích cú pháp nó trở lại đối tượng/JSON đã hoạt động cho tôi:

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

Cảm ơn bạn. Tôi đã không thử nghiệm nó, nhưng có vẻ như nó sẽ hoạt động. Nó vẫn không rõ ràng và vụng về, vì vậy tôi hy vọng rằng đội ng2 đi kèm với một cách tiếp cận trực tiếp hơn, nhưng đó là một lựa chọn nhất định. – user3221325

+0

Cảm ơn sự giúp đỡ của bạn. Tôi đã đăng câu hỏi này (với ví dụ của bạn đã được thêm) vào danh sách các vấn đề: https://github.com/angular/angular/issues/4843 – user3221325

+0

BTW, với Angular2, sự kiện xuất hiện dưới dạng một đối tượng để 'updateSelectedValue (sự kiện: chuỗi) 'hàm cần được thay đổi thành' updateSelectedValue (event: Object) 'và các đường ruột của hàm cần thay đổi thành' this.selectedObject = JSON.parse (event.target.value); ' – RHarris

33

Tôi không biết điều gì giống như trong alpha, nhưng tôi đang sử dụng phiên bản beta 12 bây giờ và điều này hoạt động tốt. Nếu bạn có một mảng của các đối tượng, tạo ra một lựa chọn như thế này:

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

Nếu bạn muốn kết hợp trên đối tượng thực tế, tôi muốn làm điều đó như thế này:

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

Các tác phẩm liên kết tìm thấy khi người dùng chọn một mục trong danh sách. Tuy nhiên, mục đã chọn không hiển thị chính xác khi trang được tải. Bạn có thể cung cấp plunker cho ví dụ làm việc? – AustinTX

+2

Không thể liên kết với 'ngModel' vì nó không phải là thuộc tính đã biết của 'chọn'. Đây là những gì tôi nhận được – John

+1

Bạn có thể cần phải nhập các formsModule – carrizal

Các vấn đề liên quan