I was surprised to find that Angular has a limited duration time window during which changes will update the view. In my case, symptoms were observed only after deployment, for user who had a high latency connection between their browser and the server.
One could mitigate this by calling $scope.$apply() after every change. But if you have to apply() all changes, then what's the point of having angular handle synchronization?