admin管理员组

文章数量:1267930

I am using Angular 18.

I have an array of "containers" containing, beside other info, an array of "products" each. I use @for to show a container-component for each container, and within those, I use @for to show a product-component for each product.

In my product component, I want to react to changes in the product, so I use ngOnChanges. However, ngOnChanges does not trigger when I edit my product - probably because it's still the same object, not completely replaced.

If I use @if(product.someParameter) or even just {{product.someParameter}} it WILL show changes immediately, but still not trigger ngOnChanges. Calling ngOnChanges manually (using a button within the component) works as expected though. I tried using a setter method, but that did not change anything.

Note: I understand WHY ngOnChanges does not trigger (I think). But I'm wondering what to do now.

I can think of three solutions for my problem:

  • A) replace the entire product whenever something changes
  • B) create another Input on the product component on a number I can count up whenever I change anything, to trigger ngOnChanges seperately
  • C) use the part of "product" I want to change as a seperate input on my product component to make sure ngOnChanges is triggered

None of them seem clean, so I wonder if there is a better way to manually tell Angular that something changed, or to trigger a code snippet in the component just by changing something outside.

Edit: I thought of a fourth solution which I prefer for the moment: I created a "changeDetector"-component which takes any input and emits a void output on ngChange. This way, the solution is contained in the product component, and I don't need to change anything in the parents.

If you need to know the usecase: I have one input-field for a barcode-scanner, that can scan containers, products and charges. Anything scanned needs to be added and displayed, with charges being shown as a dropdown. That's why I can't just refer to the properties directly and need to set the value of the dropdown via code.

I am using Angular 18.

I have an array of "containers" containing, beside other info, an array of "products" each. I use @for to show a container-component for each container, and within those, I use @for to show a product-component for each product.

In my product component, I want to react to changes in the product, so I use ngOnChanges. However, ngOnChanges does not trigger when I edit my product - probably because it's still the same object, not completely replaced.

If I use @if(product.someParameter) or even just {{product.someParameter}} it WILL show changes immediately, but still not trigger ngOnChanges. Calling ngOnChanges manually (using a button within the component) works as expected though. I tried using a setter method, but that did not change anything.

Note: I understand WHY ngOnChanges does not trigger (I think). But I'm wondering what to do now.

I can think of three solutions for my problem:

  • A) replace the entire product whenever something changes
  • B) create another Input on the product component on a number I can count up whenever I change anything, to trigger ngOnChanges seperately
  • C) use the part of "product" I want to change as a seperate input on my product component to make sure ngOnChanges is triggered

None of them seem clean, so I wonder if there is a better way to manually tell Angular that something changed, or to trigger a code snippet in the component just by changing something outside.

Edit: I thought of a fourth solution which I prefer for the moment: I created a "changeDetector"-component which takes any input and emits a void output on ngChange. This way, the solution is contained in the product component, and I don't need to change anything in the parents.

If you need to know the usecase: I have one input-field for a barcode-scanner, that can scan containers, products and charges. Anything scanned needs to be added and displayed, with charges being shown as a dropdown. That's why I can't just refer to the properties directly and need to set the value of the dropdown via code.

Share Improve this question edited Feb 27 at 8:53 Fritz Hollnbuchner asked Feb 26 at 14:44 Fritz HollnbuchnerFritz Hollnbuchner 112 bronze badges New contributor Fritz Hollnbuchner is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 2
  • I'd go with A. Or, do you need to pass the entire product in? If you pass in the constituent parts that you care about in the component, you could edit the product in-place in the parent, then pass in the property that you changed. Then, assuming you reassigned the property instead of mutating, it will pick up on the change. – Carcigenicate Commented Feb 26 at 14:49
  • Oh, that actually sounds like what you're describing in C. I'd go with C. – Carcigenicate Commented Feb 26 at 14:50
Add a comment  | 

1 Answer 1

Reset to default 1

The ngOnChanges will fire only when the inputs value has changed.

For arrays and objects that will be the memory references.

Updating the memory reference of the entire object is the best solution, because it a single line and can be understood by other DEVs instead of passing each property one by one, which is not scalable and serves no purpose but to trigger ngOnChanges.

Maybe add a comment above the object destructuring line, so that future junior DEVs understand why it is done.

本文标签: angularWhat to do when ngOnChanges does not detect a changeStack Overflow