typescript - كيفية استخدام select/option/NgFor على مجموعة من الكائنات في Angular2




(2)

لا أعرف كيف كانت الأشياء في ألفا ، لكنني أستخدم الإصدار التجريبي 12 الآن ، وهذا جيد. إذا كان لديك مجموعة من الكائنات ، فقم بإنشاء تحديد مثل هذا:

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

إذا كنت ترغب في التطابق مع الكائن الفعلي ، فسأفعل ذلك كما يلي:

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

هذا السؤال لديه بالفعل إجابة هنا:

أواجه مشكلة في إنشاء تحديد في Angular2 مدعوم بمجموعة من الكائنات بدلاً من السلاسل. كنت أعرف كيفية القيام بذلك في ngOptions باستخدام ngOptions ، لكن لا يبدو أنه يعمل في Angular2 (أنا أستخدم alpha 42).

في العينة أدناه ، لدي أربعة اختيارات ، ولكن يعمل اثنان منهم فقط.

  1. "تحديد السلسلة" عبارة عن تحديد بسيط يعتمد على السلسلة ، ويعمل بشكل جيد.
  2. كانت "تحديد كائن عبر ربط ثنائي الاتجاه" هي محاولتي لاستخدام الربط ثنائي الاتجاه. لسوء الحظ ، تفشل بطريقتين - عند تحميل الصفحة ، يعرض التحديد القيمة الخطأ (foo بدلاً من الشريط) ، وعندما يتم تحديد خيار في القائمة ، يتم إرسال القيمة "[Object Object]" إلى مخزن النسخ بدلا من القيمة الصحيحة.
  3. كانت "تحديد كائن عبر الحدث" محاولتي للحصول على القيمة المحددة من حدث $. إنه يفشل بطريقتين أيضًا - التحميل الأولي غير صحيح بنفس الطريقة مثل # 2 ، وعندما أقوم بتحديد خيار في القائمة ، يتم استرداد القيمة "[كائن كائن]" من الحدث ، لذلك لا أستطيع الحصول على القيمة الصحيحة. يتم مسح التحديد.
  4. "تحديد كائن عبر سلسلة" هو الأسلوب الوحيد الذي يستخدم كائنًا يعمل. لسوء الحظ ، إنه يعمل حقًا باستخدام صفيف السلسلة من رقم 1 وتحويل القيمة من سلسلة إلى كائن والعودة.

يمكنني أن أفعل # 4 إذا كانت هذه هي الطريقة المقصودة ، ولكن يبدو clunky جداً. هل هناك نهج آخر؟ هل أنا مبكرة جدًا في ألفا؟ هل فعلت شيء سخيف؟

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

لست خبيرًا في DOM أو Javascript / Typescript ولكني أعتقد أن علامات DOM لا يمكنها التعامل مع كائن جافا سكريبت حقيقي بطريقة أو بأخرى. ولكن وضع الكائن بالكامل كسلسلة وتحليله مرة أخرى إلى Object / 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);
  }
}




angular