Angular2 嵌套 *ngFor

11

我使用一个数组来存储一组对象和一个列表的光对象。 我想在HTML中显示第一组和所有连接到该组的灯。之后是下一组和相关灯,以此类推....

<div>
  <ul>
    <li *ngFor="let group of hueGroups">
      {{group.name}}
      <li *ngFor="let light of hueLights; let i = index">
      {{hueLights[group.lights[i]].name}}
    </li>
  </ul>
</div>



export class AppComponent implements OnInit {
  hueGroups:any[];
  hueLights:any[];

  constructor(){
    this.hueGroups = [];
    this.hueLights = [];
  }

  listAllGroups(){
   for(var g in MyHue.Groups){ //MyHue.Groups returen an array with objects
    console.log(g);
    console.log(MyHue.Groups[g].name);
    for(var id:number = 0; id < MyHue.Groups[g].lights.length; id++){
      console.log("LightID:" + MyHue.Lights[MyHue.Groups[g].lights[id]].name); // Returns the name of the Lights
    }
    this.hueGroups.push(MyHue.Groups[g]);
  }

  listAllLights(){
   for(var l in MyHue.Lights){ //MyHue.Lights returns an array with objects
    console.log(MyHue.Lights[l]);
    this.hueLights.push(MyHue.Lights[l]);
   }
  }

如果我尝试运行这个程序,我会遇到以下错误:

无法读取未定义属性“lights”

因此,我认为嵌套ngFor的语法有误。应该可以从上面调用“group”。

编辑: 这是MyHue.Groups对象的重要部分:

{action:Object
 class:"Living room"
 lights: Array(2)
   0:"3"
   1:"1"
 name:"Room1"}

在Group对象中,只有依赖于该组的灯的ID。

这是灯对象的重要部分:

 {state: Object, type: "Extended color light", name: "Couch1", modelid: "LCT007"…}

如果我将整个数组打印到控制台上,我会得到以下内容:

Object {1: Object, 3: Object, 4: Object}

所以我需要匹配哪个 Light ID 属于哪个组,并检查灯光对象的名称。


看起来你正在尝试使用 *ngFor 与一个 object*ngFor 只能用于 Arrays。你可以创建一个管道并使用 *ngFor 来迭代 hueLights 的键。 - developer033
你有这方面的例子吗?我对Angular 2还很陌生。 - WeSt
包括 hueLightshueGroups 的内容,这样更容易理解。 - developer033
好的,我已经包含了重要部分。 - WeSt
你能否包含一些示例对象?这可能可以通过单个映射来解决。 - Eeks33
我为团队添加了一个示例和轻量级对象。 - WeSt
2个回答

20

看起来你需要创建一个更简单的数据结构,其中包含在hueGroup对象的数组属性中的light对象。然后你就可以轻松地遍历你的组和模板中的每个灯光。

例如,你的模板应该像这样:

<ul>
    <li *ngFor="let group of hueGroups">
    {{group.name}}
    <ul>
        <li *ngFor="let light of group.lights">
        {{light.name}}
        </li>
    </ul>
    </li>
</ul>

你的组件应该包含一个 hueGroups 数据对象或模型以进行渲染。

hueGroups = [{
    name: "group 1",
    lights: [{
      name: "light 1"
    },{
      name: "light 2"
    }]
  },
  {
    name: "group 2",
    lights: [{
      name: "light 3"
    },{
      name: "light 4"
    }]
  }];

请查看这个 plunker,那里提供了我所说的工作示例: http://plnkr.co/edit/THXdN8zyy4aQMoo4aeto?p=preview

关键在于使用你的模板来反映支持它的组件数据的内容。除了我的示例之外,您可能还想使用 TypeScript 来为您的组和灯定义接口或类。

您的示例稍微复杂一些,因为您的模板试图呈现两个数据结构的综合(您的 hueGroup.lights 似乎是仅包含光 id 的数组)。我建议创建一个函数,该函数将带有嵌入式光对象的 hueGroup 对象,以便您的模板可以轻松迭代。以下是此类函数的示例:

更新以反映示例数据:

ngOnInit(){
    this.hueGroups = this.hueGroupSource.map((group)=>{
      let lightObjects = group.lights.map((lightID)=>{
        return this.hueLightsSource.find((light, index) => {return index === lightID});
    });
    group.lights = lightObjects;
    return group;
  });

这里有一个Plunker示例,展示了它的工作原理。 http://plnkr.co/edit/V309ULE8f6rCCCx1ICys?p=preview


谢谢你的帮助。我为小组提供了一个示例和从我的服务中接收到的轻量级对象。现在可能更有意义了。 - WeSt
我已更新我的答案,使用了您的灯光/组示例中的对象。祝你好运! - SpaceFozzy
听起来不错,但数据对象/模型的问题在于一个组中的灯光数量并不总是相同的。一个组可以有一个到多个灯光。使用额外的数据对象是否可能实现这一点? - WeSt
我的 Plunkr 示例中的一个组可以拥有任意数量的灯。你应该能够在 app.ts 文件中加载它并从组中删除一个灯 id。这里是一个 fork,展示了具有不同数量灯的组:http://plnkr.co/edit/G6gHvmu9FzkEqtyVFiGu?p=preview。不确定我的 Plunkr 没有解决什么问题? - SpaceFozzy
它几乎可以工作。我认为这一行存在问题 return index === lightID 如果我将其编辑为 return index === lightID-1 它可以正确地处理第一组,但在第二组中灯光未定义。 - WeSt
显示剩余2条评论

1

我使用以下嵌套的ngFors成功实现了此功能:

<ion-card *ngFor="let exercise of exercises">
    <ion-card-header>
      <ion-card-title>
        {{exercise.name}}
      </ion-card-title>
    </ion-card-header>
    <ion-item *ngFor="let set of exercise.sets">
      set: {{set.setNo}}
      reps: {{set.reps}}
      weight:{{set.weight}}
    </ion-item>
  </ion-card>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接