I have a parent component that creates an object myObject
with an array property myArray
. It injects this object into a child component via one-way binding. The child object uses *ngFor
to display members of the array, and it has further child components that bind to properties of the objects in the array, and so on.
I am attempting replace myObject
with a new object via myObject = new MyObject()
, or to empty myArray
via myObject.myArray.length = 0;
or myObject.myArray = [];
My expectation is that the child component would then display nothing until I re-populate the array. Instead, in any of the above cases, the child component continues to display the elements of the array as though I hadn't touchedmyObject
or myArray
at all.
I've tried a few methods of forcing a refresh that I found elsewhere on StackOverflow to no avail, so please excuse a bit of clutter in the current code.
Parent component (.ts) - This function is called when I press a certain button in the template:
create() {
this.active = false;
this.changeDetectorRef.detectChanges();
this.myObject = null;
this.myObject = new MyObject();
this.myObject.myArray = null;
this.myObject.myArray = [];
this.myObject.myArray.length = 0;
this.active = true;
this.changeDetectorRef.detectChanges();
}
I've tried to see what happens when I do console.log(myObject)
immediately after every line of this create() function. In every single case, what I get in the console looks like this:
MyObject {myArray: Array(0)}
It looks right, but when I expand that object in the console, it shows that myArray
actually still has all of the items it had previously.
Parent component template (.html)
<my-child *ngIf="active"
[myObject]="myObject"
></my-child>
Child component (.ts)
@Input() myObject:MyObject = new MyObject();
Child component template (.html)
<ng-container *ngFor="let item of myObject.myArray">
<another-child-component
[item]="item"
etc.
></another-child-component>
</ng-container>
I am logging every time the child component's ngOnInit()
function is called, so I know that the active flag and the changeDetectorRef are forcing it to reinitialize as desired. I also can see the MyObject() constructor getting called enough times to know that the child component is re-instantiating its myObject
every time it gets reinitialized.
Yet no matter what I do or where I call it from, I can see that the whole system is still displaying the old myObject
and if I call console.log(this.myObject)
, no matter where or when, it will always output the old copy.
I don't understand this. Why are my child components hanging onto their old objects even after re-initialization?