angular/angular.js — pull request #3491 by pheuter (2013-08-07 15:44:46+00:00)
Title: Allow directive's bi-directional isolate scope to do deep equality check

### Background

Consider the following directive:

```js
myApp.directive('listUsers', function() {
return {
restrict: 'E',
template: "

{{user.name}} - {{user.age}}

",
scope: {
users: '='
}
};
});
```

It sets up bi-directional binding to the parent scope's `users` property that it receives via an attribute. In this particular situation, it expects an array of user objects and lists user names and their respective ages.

We could use this directive like so.

```html

```

Everything works just fine. At least until we decide to use a filter.

```html

```

If you look in the browser console, you will see something along the lines of: `10 $digest() iterations reached. Aborting!`

The problem is that `filter`, along with many other functions that mutate arrays, return a copy and not the original array. During the $digest [comparison step](https://github.com/angular/angular.js/blob/master/src/ng/rootScope.js#L527-L530), the array value is deemed as changed (since a new reference is returned even though the actual elements in the array have not changed) and the watchers are called again and again.

### Proposition

Allow optional "deep" equality checks on bi-directional scope values to avoid unnecessary digests.

This pull request introduces an optional argument, `*`, that can be passed to a directive's scope definition. When passed, a deep [equality](https://github.com/angular/angular.js/blob/master/src/Angular.js#L682) check will be forced when determining if watcher value has changed.

Now, the example above will work properly with just a minor tweak to the directive's scope definition:

```js
myApp.directive('listUsers', function() {
return {
...
scope: {
users: '=*'
}
};
});
```