I have a similar issue to this question, but it seems that question is out of date as neither of the 2 answers work for me.
The child component is simply rendering data from a complex object called Proposal
passed as an input (it has no user controls at all, so does not need to fire any events or pass anything out).
@Component({
selector: 'fb-proposal-document',
templateUrl: './proposal-document.component.html',
styleUrls: ['./proposal-document.component.css']
})
export class ProposalDocumentComponent implements OnInit, OnDestroy {
@Input() proposal: Proposal;
constructor()
}
The pertinent part of the template is this, iterating an array and checking a property to display different text using *ngIf
:
<li class="section" *ngFor="let qp of proposal?.quoted_products">
<li class="section" *ngFor="let room of qp?.rooms">
...
<div class="row">
<div class="col-md-12">
Supply
<span *ngIf="room.is_fitted">
and install
</span>
<span *ngIf="!room.is_fitted">
only
</span>
</div>
</div>
...
</li>
</li>
In the parent, the user can click a checkbox to change 'is_fitted' to true or false. The parent is using a domain-drive form. In the ngOnInit
of the parent is this code:
this.myForm.controls['isFitted'].valueChanges.subscribe(
value => {
this.proposal.is_fitted = value;
let qp = this.proposal.quoted_products[this.qpCurrentIndex];
qp.rooms.forEach(function(room) {
room.is_fitted = value;
});
}
);
which correctly updates the property. I can see that if I console.log
it. So the question is, how can I get the child to refire/re-process the *ngIf
when the embedded room.is_fitted
values change?
I have tried implementing this idea, using ViewChild, so the above code in ngOnInit then becomes:
this.myForm.controls['isFitted'].valueChanges.subscribe(
value => {
this.proposal.is_fitted = value;
let qp = this.proposal.quoted_products[this.qpCurrentIndex];
qp.rooms.forEach(function(room) {
room.is_fitted = value;
});
this.proposalDocument.notifyChange(this.proposal);
}
);
but that does not work either. My notifyChange in the child is called successfully:
notifyChange(proposal: Proposal) {
console.log('I changed');
this.proposal = proposal;
}
but the view does not update - the *ngIf
logic does not get reprocessed.
I took out all the code and wrote it again from scratch and my very fist attempt now works:
this.myForm.controls['isFitted'].valueChanges.subscribe(
value => {
this.proposal.is_fitted = value;
let qp = this.proposal.quoted_products[this.qpCurrentIndex];
qp.rooms.forEach(function(room) {
room.is_fitted = value;
});
}
);
I don't need to notify the child at all. The view updates automatically.
I was convinced from everything I have read that complex objects do not update deep properties - only if you change the reference to the object itself. But here I am now changing deep properties and I am not notifying the child by calling ngOnChanges, and it works. Go figure.