mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
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
This commit is contained in:
parent
ed78f0d830
commit
7da2bdb82a
2 changed files with 37 additions and 18 deletions
|
|
@ -655,28 +655,31 @@ function equals(o1, o2) {
|
|||
if (o1 === null || o2 === null) return false;
|
||||
if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
|
||||
var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
|
||||
if (t1 == t2 && t1 == 'object') {
|
||||
if (isArray(o1)) {
|
||||
if ((length = o1.length) == o2.length) {
|
||||
for(key=0; key<length; key++) {
|
||||
if (!equals(o1[key], o2[key])) return false;
|
||||
if (t1 == t2) {
|
||||
if (t1 == 'object') {
|
||||
if (isArray(o1)) {
|
||||
if ((length = o1.length) == o2.length) {
|
||||
for(key=0; key<length; key++) {
|
||||
if (!equals(o1[key], o2[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
|
||||
keySet = {};
|
||||
for(key in o1) {
|
||||
if (key.charAt(0) !== '$' && !isFunction(o1[key]) && !equals(o1[key], o2[key])) {
|
||||
return false;
|
||||
}
|
||||
keySet[key] = true;
|
||||
}
|
||||
for(key in o2) {
|
||||
if (!keySet[key] && key.charAt(0) !== '$' && !isFunction(o2[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
|
||||
keySet = {};
|
||||
for(key in o1) {
|
||||
if (key.charAt(0) !== '$' && !isFunction(o1[key]) && !equals(o1[key], o2[key])) {
|
||||
return false;
|
||||
}
|
||||
keySet[key] = true;
|
||||
}
|
||||
for(key in o2) {
|
||||
if (!keySet[key] && key.charAt(0) !== '$' && !isFunction(o2[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (t1 == 'function' && o1.$unboundFn) return o1.$unboundFn === o2.$unboundFn;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,6 +248,22 @@ describe('Scope', function() {
|
|||
}));
|
||||
|
||||
|
||||
it('should watch functions', function() {
|
||||
module(provideLog);
|
||||
inject(function($rootScope, log) {
|
||||
$rootScope.fn = function() {return 'a'};
|
||||
$rootScope.$watch('fn', function(scope, fn) {
|
||||
log(fn());
|
||||
});
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('a');
|
||||
$rootScope.fn = function() {return 'b'};
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('a; b');
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
it('should prevent $digest recursion', inject(function($rootScope) {
|
||||
var callCount = 0;
|
||||
$rootScope.$watch('name', function() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue