Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
741 views
in Technique[技术] by (71.8m points)

angular - Passing values between child components in ngFor

How do I pass a value between child components that are populated using *ngFor ?.

I have tried using the @output decorator patterns and it results in erroneous behavior.

  1. How do to correctly use the @output. why does the expected results are not obtained. ?
  2. Is there any other way to achieve this functionality other than changing the data model?.

A JSON array is specified app.component.ts and it has a field salary. I would want to display a total field salary as we loop through the array and display it in the child component.

Here the goal is to print out the total salary dynamically as the elements get iterated. I try to achieve this using @output decorator by calculating the total salary of the child and then send it to the parent.

app.component.html

<div *ngFor="let person of persons">
<app-child [name]="person.name" [salary]= "person.salary" [totalsalary] = "totalsalary" 
(totalSalary)="setTotalSalary($event)">

 </app-child>
 <div>

  import { Component, Input } from '@angular/core';

app.component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @Input() totalsalary:number=0;

persons = [{
  "name":"x",
  "salary":1
},{
  "name":"s",
  "salary":2
},
{
  "name":"y",
  "salary":2
}
]
setTotalSalary(totalSalary:number) {
 //   console.log("total  salary" +this.totalsalary)
  this.totalsalary = totalSalary;
}
}

child.component.ts

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  @Input() name!:string;
  @Input() salary!:number;
  @Input() totalsalary!:number;
  @Output() totalSalary = new  EventEmitter<number>();

  constructor() { }

  ngOnInit(): void {
  }

  displayTotalSalary() {
    console.log("current salary"+this.salary)
    console.log("total  salary" +this.totalsalary)
let sum = Number(this.salary) + Number(this.totalsalary)
    this.totalSalary.emit(sum);
    return  Number(sum)
  }

}

child.component.html

<p>{{name}}</p>
<p>{{salary}}</p>
<p>{{displayTotalSalary()}}</p>

Expected Result :

x

1

1

s

2

3

y

2

5

Received :

x

1

6

s

2

8

y

2

10
question from:https://stackoverflow.com/questions/65642951/passing-values-between-child-components-in-ngfor

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

displayTotalSalary() is being called two times for each child, first time for each child(taking the totalSalary to 1+2+2 =5) then again for each child that's why you are getting 5+1=6, 6+2=8 and 8+2=10.

This is because of the function call displayTotalSalary() in template, moving the call from template to the ts files fixes the issue.

ngOnInit(): void { this.salaryToDisplay = this.displayTotalSalary(); }

and in child template use<p>{{salaryToDisplay}}</p>

To know why function call in template is being called multiple times.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...