I am using angular 4. I am a bit new to it although i had used Angular JS.
I have a parent component which has an array of objects
people: Person[]; //array of Person model
And in the parent component the user modifies people array through its view
Now there is a child component(personComponent) in the parent components view that iterates through the people array like so
<person *ngFor="let person of people; let i = index" [person]="person">
The child component shows percentges of each person in the personComponent
@Input() person:Person; //person model
percent:number;
ngOnInit(){
this.percent = this.person.percent;
}
Now in the parent component, when a new person is added to the people array, each child component is supposed to have a new percent.
So i created a method in the parent component that calculates the percent of each person
setPercent(){
this.people.forEach((p)=>{
p.percent = Math.round((p.value/this.total_amount)*100) //total amount is a variable in the parent component
})
}
Now every time a new person is added the setPerson method is called...the problem is that the child component does not update its data and the percent of each person in the people array is not updated.
I have tried using ngOnChanges on the child components person variable but that did not update the child components data and hence the child components view did not change as well. What can i do pls.
@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.
In your Person
component, you take the percentage value on initialization and no longer update it. Instead of doing that, you could use the person
property, that has the always up to date value. So you should be able to use it as
{{person.percentage}}
in your template.
You can use the onChanges lifecycle hook.
// Child component
import { Component, OnChanges, SimpleChanges } from '@angular/core';
ngOnChanges(changes: SimpleChanges) {
if (changes['person']) {
console.log(changes['person'].currentValue);
}
}
On your child component use the following:
import { ChangeDetectionStrategy } from '@angular/core';
@Component({
// your selector and template
changeDetection: ChangeDetectionStrategy.OnPush
})
and in your parent component try the following:
import {ChangeDetectionRef} from '@angular/core';
and Inject it in the constructor:
constructor(private cd:ChangeDetectorRef){}
and in your method that update the percentages:
setPercent(){
this.people.forEach((p)=>{
p.percent = Math.round((p.value/this.total_amount)*100) //total amount is a
variable in the parent component
});
// TRY THIS
this.cd.detectChanges();
// OR THIS
this.cd.markForCheck();
}
This code will tell the change detection to check of changes on your component and it's children.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With