In the world of AngularJS, the $watch
function comes with an interesting twist - it has an optional third parameter.
By default, this parameter is set to false
, which means the watch will only trigger if the watched reference changes. But if you set it to true
, the watch will be triggered when the watched object itself changes, as determined by angular.equals
.
However, I find myself in need of a way to make the watch fire its function when either the watched reference or its content changes. Is there a solution to achieve this dual functionality?
To illustrate the challenges I'm facing:
Imagine I have an array of editable objects:
var allItems = [{id: 1, a: []}, {id: 2, a: [2, 3, 5]}, {id: 3, a: [4, 6]}, {id: 4, a: []}];
A specific scope in my editor holds a reference to the value of the a
property. For example, after selecting item 1:
$scope.currentItem = [];
Additionally, a watch is placed on this field to compare values:
$scope.$watch('currentItem', watchFunc, true);
Now, consider two scenarios:
- The user modifies the selected item's
[]
to[4, 6]
using the editor UI. - The user switches to item 3.
From within watchFunc
, these changes may seem identical at first glance. To distinguish between them, I must somehow keep track of the previous ID and compare it to the current one. This allows me to differentiate whether a new item was selected or just updated.
Yet, complications arise in situations like:
- Selecting item 1.
- Switching to item 4.
- Performing edits on item 4.
Here lies the issue - the second action won't trigger the watch based on angular.equals
. Consequently, the selected item ID won't update during the selection change. Only later, in step 3, will the different item ID be recognized, leading to the oversight of the actual editing action.
Of course, this scenario simplifies the complexity; in reality, my data structure involves nested arrays of objects with diverse properties.