Angular2 嵌套 *ngFor [英] Angular2 nested *ngFor

查看:21
本文介绍了Angular2 嵌套 *ngFor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用一个数组来存储一个组对象列表和一个灯光对象列表的数组.我想显示 html 中的第一组以及所有连接到该组的灯.之后是下一组和相关的灯等等....

<ul><li *ngFor="让一组色调组">{{团队名字}}<li *ngFor="让hueLights的光亮;让我=索引">{{hueLights[group.lights[i]].name}}

导出类 AppComponent 实现 OnInit {色调组:任何[];色调灯:任何[];构造函数(){this.hueGroups = [];this.hueLights = [];}listAllGroups(){for(var g in MyHue.Groups){//MyHue.Groups 返回一个包含对象的数组控制台日志(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);//返回灯光的名称}this.hueGroups.push(MyHue.Groups[g]);}listAllLights(){for(var l in MyHue.Lights){//MyHue.Lights 返回一个包含对象的数组console.log(MyHue.Lights[l]);this.hueLights.push(MyHue.Lights[l]);}}

}

如果我尝试运行它,我会收到错误

<块引用>

无法读取未定义的属性 'lights'

所以我认为嵌套 ngFor 的语法是错误的.应该可以从上面调用组".

这是 MyHue.Groups 对象外观的重要部分:

{action:Object课程:客厅"灯:阵列(2)0:3"1:1"名称:房间1"}

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

这是灯光对象外观的重要部分:

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

如果我将孔阵列打印到控制台,我会得到这样的结果:

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

所以我必须匹配哪个Light ID在哪个Group中,然后检查名称的light Object

解决方案

看起来您需要创建一个更简单的数据结构,其中您的灯光对象包含在您的 HueGroup 对象的数组属性中.然后,您将能够轻松地遍历您的组以及模板中的每个灯.

例如,您的模板应该看起来更像这样:

    <li *ngFor="让一组色调组">{{团队名字}}<ul><li *ngFor="let light of group.lights">{{light.name}}

并且您的组件应包含要呈现的 hueGroups 数据对象或模型.

hueGroups = [{名称:第1组",灯: [{名称:光1"},{名称:《光2》}]},{名称:第2组",灯: [{名称:《光3》},{名称:《光4》}]}];

查看这个 plunker 以了解我的意思:http://plnkr.co/edit/THXdN8zyy4aQMoo4aeto?p=preview

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

你的例子有点复杂,因为你的模板试图呈现两个数据结构的合成(你的 HueGroup.lights 似乎只是光 id 的数组).我建议创建一个函数来创建一个带有嵌入光对象的 HueGroup 对象,您的模板可以轻松迭代.这是此类函数的示例:

更新以反映示例数据:

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

}

这是一个在工作示例中展示它的plunker.http://plnkr.co/edit/V309ULE8f6rCCCx1ICys?p=preview

I use an array to store a list of group objects and an array of a list of light objects. I want to show the first group in the html and all connected lights to that group. After that the next group and the related lights and so on....

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

}

If I try to run this I get the error

Cannot read property 'lights' of undefined

So I think the syntax is wrong for the nested ngFor. It should be possible to call "group" from above.

EDIT: This is the important part of how an object of the MyHue.Groups looks like:

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

In the Group object there is only the ID of the lights which are depending to this group

This is the important part of how a light object looks like:

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

This is what I get if I print the hole array to the console:

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

So I have to match which Light ID is in which Group, then check the light Object for the name

解决方案

Looks like you need to create a simpler data structure where your light objects are contained in an array property of your hueGroup objects. Then you'll be able to iterate easily through your groups, and each of their lights in your template.

For example, your template should look more like this:

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

And your component should contain a hueGroups data object or model to render.

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

Check out this plunker for a working example of what I mean: http://plnkr.co/edit/THXdN8zyy4aQMoo4aeto?p=preview

The key here is using your template to reflect the content of the component's data that's backing it. Beyond my example, you might want to use typescript to define an interface or class for your groups and lights.

Your example is a little more complicated because your template is trying to render a synthesis of two data structures (your hueGroup.lights seem to be arrays of just light ids). I'd recommend making a function that creates a hueGroup object with embedded light objects your template can iterate over easily. Here's an example of such a function:

Updated to reflect the example data:

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

}

Here is a plunker showing it in a working example. http://plnkr.co/edit/V309ULE8f6rCCCx1ICys?p=preview

这篇关于Angular2 嵌套 *ngFor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆