【问题标题】:Accessing current element of *ngFor Loop in TypeScript Code (Angular 4)在 TypeScript 代码中访问 *ngFor 循环的当前元素(Angular 4)
【发布时间】:2018-07-29 19:05:57
【问题描述】:

我的 json 文件中有 5 个人的数组。每个人都有一个包含项目的数组。 在我的 html 代码中,我使用 *ngFor 循环显示他们的名字。我还想显示物品价格的总和。 为了一起计算他们商品的价格,我在我的 TypeScript 代码中使用了一个函数。我正在控制台中显示总价格。

问题是,我在打字稿文件中使用的当前代码再次循环遍历这些人。所以我用 *ngFor 循环遍历我的 html 中的人员,在此我调用函数 getTotal(),它再次循环遍历人员 。当然,我只想循环一次。

json

  "persons":[
    {
      "name": "Peter",
      "items": [
        {
          "name": "pen",
          "price": 1.50
        },
        {
          "name": "paper",
          "price": 2.00
        }
      ]
    },
    {
      "name": "Maria",
      "items": [
        {
          "name": "scissors",
          "price": 4.00
        },
        {
          "name": "stickers",
          "price": 3.00
        }
      ]
    }

    // three more persons
  ]

html

<div *ngFor="let person of persons"> <!--here I'm looping through the persons-->
  <p>{{person.name}}</p>
  <p>Total <span>{{getTotal()}}</span></p> <!--here I'm calling the function, which will loop through persons again-->
</div>

打字稿

getTotal() {
    for(let person of this.persons){ //here I'm looping through the persons again (what I actually don't want)
      let total = 0;
      for(let item of person.items){
          total = total + item.price;
      }
     console.log(total);
    }
}

现在我的问题是: 如您所见,我在我的 html 代码中使用 *ngFor 和在 getTotal() 中的 typescript 代码中循环访问人员。我这样做只是为了在以下循环中访问他们的项目 (person.items)。我想摆脱第一个循环并使用 *ngFor 访问我正在循环的当前元素。我怎样才能做到这一点,甚至有可能吗?

【问题讨论】:

  • 我会在显示之前在组件中进行计算,主要是因为在模板中调用方法通常是一个坏主意,因为它在每次更改检测时都会调用。
  • 请检查更新的答案,正如@Alex刚刚在评论中所说的那样实施

标签: json angular loops typescript ngfor


【解决方案1】:

改一下就好了

作为对您问题的回答,从模板端调用一个函数,这里 它是,但更喜欢第二种方法

模板端:

<p>Total <span>{{getTotal(person.items)}}</span></p> 

组件端:

getTotal(items) {
    let total = 0 ;
    for(let item of items){
        total = total + item.price;
    }
    return total;
}

更好的方法是,从组件端处理所有数据,而不是从模板端调用它

为什么?

在上述情况下,每次视图更改或数据更改时都会调用函数。

组件端:

constructor(){
    this.persons.map(person => {
        person.total = person.items.reduce((pv,cv) => {
            return cv.price + pv.price;
        });
        return person;
    });
}

模板端:

<p>Total <span>{{person.total)}}</span></p> 

【讨论】:

  • 好的,感谢更新代码。但老实说,我对 TypeScript 很陌生,我并不真正了解您的代码的作用。我不明白 "person.total = person.items.reduce((pv,cv) =>" 是做什么的。请给我一个简短的解释吗?非常感谢!
  • 好的那么建议检查一下javascript的reduce函数 (pv - previousValue , cv - currentValue) , developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 非常感谢!现在我更好地理解了这个功能
  • 你好。我试过你的代码,但我得到了错误:未捕获(承诺):TypeError:无法读取未定义的属性'map'
  • @BlueCat ,构造函数中的代码只是示例,您应该在初始化 persons 时调用该部分,您会收到错误,因为您试图在初始化 persons 之前调用它跨度>
【解决方案2】:

将人发送到 getTotal 方法。我的意思是:

getTotal(person:any){
   let total: number = 0;
   for(item of person.items){
       total += item.price;
   }
   return total;
}

所以在你的 HTML 中它必须是:

<div *ngFor="let person of persons"> 
   <p>{{person.name}}</p>
   <p>Total <span>{{getTotal(person)}}</span></p> <!-- take a look how 
       I send the current person in the *ngFor loop -->
</div>

【讨论】:

    【解决方案3】:

    您可以在getTotal 函数中传递人员,并且可以在其中添加项目的价格而无需再次循环

    <div *ngFor="let person of persons">
      <p>{{person.name}}</p>
      <p>Total <span>{{ getTotal(person) }}</span></p> <!--here I'm calling the function, which will loop through persons again-->
    </div>
    

    打字稿

    getTotal(person) { 
          let total = 0;
          for(let item of person.items){
              total = total + item.price;
          }  
          return total;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 2014-12-16
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      相关资源
      最近更新 更多