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

Commit 7230c9a

Browse files
erwinmombaySomeKittens
authored andcommitted
bug(scopes): fix scope decorator to not break one time binding
1 parent 05685a9 commit 7230c9a

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

src/modules/scopes.js

+10
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ function decorateRootScope($delegate, $parse) {
7878
var _watch = scopePrototype.$watch;
7979
var _digestEvents = [];
8080
scopePrototype.$watch = function (watchExpression, reactionFunction) {
81+
if (typeof watchExpression === 'string' &&
82+
isOneTimeBindExp(watchExpression)) {
83+
return _watch.apply(this, arguments);
84+
}
8185
var watchStr = humanReadableWatchExpression(watchExpression);
8286
var scopeId = this.$id;
8387
if (typeof watchExpression === 'function') {
@@ -307,3 +311,9 @@ function humanReadableWatchExpression (fn) {
307311
}
308312
return fn.toString();
309313
}
314+
315+
function isOneTimeBindExp(exp) {
316+
// this is the same code angular 1.3.15 has to check
317+
// for a one time bind expression
318+
return exp.charAt(0) === ':' && exp.charAt(1) === ':';
319+
}

test/scopes.spec.js

+62
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,68 @@ describe('ngHintScopes', function() {
1010
$rootScope = _$rootScope_;
1111
}));
1212

13+
describe('scope.$watch', function() {
14+
var scope;
15+
16+
beforeEach(function() {
17+
scope = $rootScope.$new();
18+
scope.a = { b: 'hello' };
19+
spyOn(hint, 'emit');
20+
});
21+
22+
it('should run perf timers for string expressions', function() {
23+
var calls = hint.emit.calls;
24+
scope.$watch('a.b', function() {});
25+
expect(calls.count()).toBe(0);
26+
27+
scope.$apply();
28+
var evt = calls.mostRecent().args[1].events[0];
29+
expect(calls.count()).toBe(1);
30+
expect(evt.time).toEqual(jasmine.any(Number));
31+
evt.time = null
32+
expect(evt).toEqual({
33+
eventType: 'scope:watch',
34+
id: scope.$id,
35+
watch: 'a.b',
36+
time: null
37+
});
38+
39+
scope.$apply();
40+
expect(calls.count()).toBe(2);
41+
var evt = calls.mostRecent().args[1].events[0];
42+
expect(evt.time).toEqual(jasmine.any(Number));
43+
evt.time = null
44+
expect(evt).toEqual({
45+
eventType: 'scope:watch',
46+
id: scope.$id,
47+
watch: 'a.b',
48+
time: null
49+
});
50+
51+
});
52+
53+
if (angular.version.minor >= 3) {
54+
it('should not run perf timers for one time bind expressions', function() {
55+
var calls = hint.emit.calls;
56+
scope.$watch('::a.b', function() {});
57+
expect(calls.count()).toBe(0);
58+
59+
scope.$apply();
60+
var evt = calls.mostRecent().args[1].events[0];
61+
// this is the watch angular registers and deregisters on $$postDigest
62+
// for one time watch expressions
63+
expect(calls.count()).toBe(1);
64+
expect(evt.eventType).toBe('scope:watch');
65+
expect(evt.watch).toBe('oneTimeWatch');
66+
67+
scope.$apply()
68+
var evt = calls.mostRecent().args[1].events[0];
69+
expect(calls.count()).toBe(2);
70+
expect(evt).toBeUndefined();
71+
});
72+
}
73+
});
74+
1375
// TODO: revisit this when I figure out a good way to make this
1476
// perform; see: https://github.com/angular/angular-hint-scopes/issues/2
1577
// describe('$rootScope.$watch', function() {

0 commit comments

Comments
 (0)