When you click "Update Age", only the first list updates the age, because all others have
a one-time binding on the age property. If you then click "Copy", the current friend list
is copied, and now the second list updates the age, because the identity of the collection items
has changed and the list must be re-rendered. The 3rd and 4th list stay the same, because all the
items are already known according to their tracking functions.
When you click "Remove First", the 4th list has the wrong age on both remaining items. This is
due to tracking by $index: when the first collection item is removed, ngRepeat reuses the first
DOM element for the new first collection item, and so on. Since the age property is one-time
bound, the value remains from the collection item which was previously at this index.
track by $id(friend) (default):
John is 25 years old.
Mary is 40 years old.
Peter is 85 years old.
track by $id(friend) (default), with age one-time binding: