I am creating a component to edit an array of simple objects.
According to the Angular 1.7.2 documentation, components should use one-way (< and @) bindings where possible, and use & bindings for output callbacks. It states:
For components however, only the component that owns the data should modify it, to make it easy to reason about what data is changed, and when.
Regarding input objects and arrays, it states specifically:
The general rule should therefore be to never change an object or array property in the component scope.
My component accepts an array of objects as input, provides a way to edit the properties on these objects, and insert and delete objects to the array. The component needs to update its view if the object array is changed elsewhere. The component does not own the data it accepts as input.
I've defined the bindings of the component as follows:
{
objects: "<",
addObject: "&",
deleteObject: "&",
updateObject: "&"
}
Considering that the objects data should not be changed by the component, the component must make a local copy of the objects during $onChanges. Changes to the local copy are then propagated to the parent via the callbacks.
However, this creates a disconnect between the local copy and the original data. $onChanges is only triggered if the objects reference itself is reassigned.
The solution to that is to place a watch on objects with object equality that triggers the creation of the local copy. This seems counter to what components are supposed to do, and I've seen elsewhere that $watch used in components is seen as a crutch and/or smelly design.
This plunker demonstrates the issue.
What is the correct way to implement this design?