【问题标题】:How to use select/option/NgFor on an array of objects in Angular2 [duplicate]如何在Angular2中的对象数组上使用选择/选项/ NgFor [重复]
【发布时间】:2016-01-15 21:11:21
【问题描述】:

我在 Angular2 中创建由对象数组而不是字符串支持的选择时遇到问题。我知道如何在 AngularJS 中使用 ngOptions,但它似乎在 Angular2 中不起作用(我使用的是 alpha 42)。

在下面的示例中,我有四个选择,但只有两个有效。

  1. 'Select String' 是一个简单的基于字符串的选择,它运行良好。
  2. “通过 2 向绑定选择对象”是我尝试使用 2 向绑定的尝试。不幸的是,它以两种方式失败 - 当页面加载时,选择显示错误的值(foo 而不是 bar),当我在列表中选择一个选项时,值 '[object Object]' 被发送到后备存储而不是正确的值。
  3. “通过事件选择对象”是我尝试从 $event 中获取选定值的尝试。它也以两种方式失败 - 初始加载与 #2 一样不正确,当我在列表中选择一个选项时,从事件中检索到值 '[object Object]',所以我不能获得正确的价值。选择被清除。
  4. “通过字符串选择对象”是使用有效对象的唯一方法。不幸的是,它确实可以通过使用 #1 中的字符串数组并将值从字符串转换为对象并返回。

如果这是预期的方式,我可以执行 #4,但它看起来很笨重。还有另一种方法吗?我在 Alpha 阶段是不是太早了?我做了什么傻事吗?

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

【问题讨论】:

  • 亲爱的时间旅行者在 2016 年或以后来到这里! linked question 有一个 better answer,它不使用 hacky object-to-json-to-object 转换。
  • 是的。不过,奇怪的是,当这个问题比另一个问题早 5 个月时,它被标记为另一个问题的副本。

标签: typescript angular


【解决方案1】:

我不知道 Alpha 版的情况如何,但我现在使用的是 Beta 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>

【讨论】:

  • 当用户在列表中选择一个项目时,该绑定起作用。但是,加载页面时,所选项目无法正确显示。你能提供工作示例的 plunker 吗?
  • 无法绑定到“ngModel”,因为它不是“select”的已知属性。这就是我得到的
  • 您可能需要导入 formsModule
【解决方案2】:

我不是 DOM 或 Javascript/Typescript 方面的专家,但我认为 DOM-Tags 无法以某种方式处理真正的 javascript 对象。但是将整个对象作为字符串放入并将其解析回 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);
  }
}

【讨论】:

  • 谢谢。我还没有测试过,但看起来它会起作用。它仍然不明显且笨拙,所以我希望 ng2 团队提出更直接的方法,但这是一个确定的选择。
  • 感谢您的帮助。我将此问题(添加了您的示例)发布到问题列表中:github.com/angular/angular/issues/4843
  • 顺便说一句,对于 Angular2,事件作为对象进入,因此需要将 updateSelectedValue(event:string) 函数更改为 updateSelectedValue(event: Object),并且函数的核心需要更改为 this.selectedObject = JSON.parse(event.target.value);
  • 同样使用 Angular2,我们可以摆脱 stringify() 函数并简单地使用 json 管道。 (例如[ngModel] = "selectedObject | json"[value]="o | json"
  • April 28 开始,语法*ngFor="#o of objArray" 不再有效。现在,您必须使用*ngFor="let o of objArray"
猜你喜欢
  • 1970-01-01
  • 2021-12-06
  • 2016-06-30
  • 2017-03-11
  • 2016-10-10
  • 1970-01-01
  • 2016-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多