Reputation: 393
I have a problem with Anglular 8 and binding input parameters from parent component to child component. I have the following setup:
-app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'parent-child-binding';
showTitle: boolean = true;
childData = [];
onBoolean(){
this.showTitle = !this.showTitle;
}
onComplexAdd(){
this.childData.push("data 4");
this.childData.push("data 5");
}
onComplexEdit(){
this.childData[0] = "data 1 edited";
this.childData[1] = "data 2 edited";
}
onComplexNew(){
this.childData = [
"data 1",
"data 2",
"data 3"
]
}
}
-app.component.html
<button (click)="onBoolean()">Boolean Bind</button>
<button (click)="onComplexNew()">Complex Object New</button>
<button (click)="onComplexEdit">Complex Object Edit</button>
<button (click)="onComplexAdd">Complex Object Add</button>
<app-child [data] = "childData" [showTitle]="showTitle"></app-child>
-child.component.ts
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges {
@Input() showTitle : boolean = true;
@Input() data : Array<any>;
constructor() { }
ngOnChanges(changes: SimpleChanges): void {
console.log(changes);
}
ngOnInit(): void {
}
}
-child.component.html
<h3 *ngIf="showTitle">Hello from child</h3>
<p *ngFor="let item of data">{{item}}</p>
So when I start I see the following:
and the console:
When I click on the first button, as expected the title Hello from child
shows and disappears.
When I click on the second button, as expected I see:
and the console:
When I click on the third and forth buttons, nothing happens, not in the UI or console (the onChanges
method seems that is not firing).
An I doing something wrong, or this that I want to achieve is not possible?
Best regards, Julian
EDIT: After a comment and an answer from @MBB and @Apoorva Chikara, I've edited the code.
<button (click)="onBoolean()">Boolean Bind</button>
<button (click)="onComplexNew()">Complex Object New</button>
<button (click)="onComplexEdit()">Complex Object Edit</button>
<button (click)="onComplexAdd()">Complex Object Add</button>
<app-child [data] = "childData" [showTitle]="showTitle"></app-child>
The edition made the buttons to act (do something), but it is not what I expect.
What I mean:
When I click on the Complex Object Edit
button in the UI I see:
But in the console, there is no ngOnChanges
callback firing, but the binded object has changed, as we can see on the print screen (<p *ngFor="let item of data">{{item}}</p>
) fired and printed out the new values.
The same happens when I click on the Complex Object Add
button. In the UI I see:
But in the console the ngOnChanges
callback is not firing, but the UI is containing the new added data.
I'm confused, can anyone advice please?
Upvotes: 0
Views: 604
Reputation: 8773
You have a very simple fix, you are not calling a function instead assigning its definition :
<button (click)="onComplexEdit()">Complex Object Edit</button> // call it as a function
<button (click)="onComplexAdd()">Complex Object Add</button>// call it as a function
The issue, you are facing for NgonChanges
is due to the arrays passed by reference, this has a good explanation why this happens.
Upvotes: 2