Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 7da2bdb

Browse files
committed
fix(scope): support watching functions
currently we run into infinite digest if a function is being watched as an expression. This is because we generate bound function wrapper when the watch is processed via parser. I'm not too keen on the solution because it relies on the unbound fn that is being exposed for other reasons, but I can't think of a better way to deal with this right now
1 parent ed78f0d commit 7da2bdb

File tree

2 files changed

+37
-18
lines changed

2 files changed

+37
-18
lines changed

src/Angular.js

+21-18
Original file line numberDiff line numberDiff line change
@@ -655,28 +655,31 @@ function equals(o1, o2) {
655655
if (o1 === null || o2 === null) return false;
656656
if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
657657
var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
658-
if (t1 == t2 && t1 == 'object') {
659-
if (isArray(o1)) {
660-
if ((length = o1.length) == o2.length) {
661-
for(key=0; key<length; key++) {
662-
if (!equals(o1[key], o2[key])) return false;
658+
if (t1 == t2) {
659+
if (t1 == 'object') {
660+
if (isArray(o1)) {
661+
if ((length = o1.length) == o2.length) {
662+
for(key=0; key<length; key++) {
663+
if (!equals(o1[key], o2[key])) return false;
664+
}
665+
return true;
663666
}
664-
return true;
665-
}
666-
} else {
667-
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
668-
keySet = {};
669-
for(key in o1) {
670-
if (key.charAt(0) !== '$' && !isFunction(o1[key]) && !equals(o1[key], o2[key])) {
671-
return false;
667+
} else {
668+
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
669+
keySet = {};
670+
for(key in o1) {
671+
if (key.charAt(0) !== '$' && !isFunction(o1[key]) && !equals(o1[key], o2[key])) {
672+
return false;
673+
}
674+
keySet[key] = true;
672675
}
673-
keySet[key] = true;
674-
}
675-
for(key in o2) {
676-
if (!keySet[key] && key.charAt(0) !== '$' && !isFunction(o2[key])) return false;
676+
for(key in o2) {
677+
if (!keySet[key] && key.charAt(0) !== '$' && !isFunction(o2[key])) return false;
678+
}
679+
return true;
677680
}
678-
return true;
679681
}
682+
if (t1 == 'function' && o1.$unboundFn) return o1.$unboundFn === o2.$unboundFn;
680683
}
681684
return false;
682685
}

test/service/scopeSpec.js

+16
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,22 @@ describe('Scope', function() {
248248
}));
249249

250250

251+
it('should watch functions', function() {
252+
module(provideLog);
253+
inject(function($rootScope, log) {
254+
$rootScope.fn = function() {return 'a'};
255+
$rootScope.$watch('fn', function(scope, fn) {
256+
log(fn());
257+
});
258+
$rootScope.$digest();
259+
expect(log).toEqual('a');
260+
$rootScope.fn = function() {return 'b'};
261+
$rootScope.$digest();
262+
expect(log).toEqual('a; b');
263+
})
264+
});
265+
266+
251267
it('should prevent $digest recursion', inject(function($rootScope) {
252268
var callCount = 0;
253269
$rootScope.$watch('name', function() {

0 commit comments

Comments
 (0)