Skip to content

Commit 8452a54

Browse files
committed
perf($interpolate): move $sce/stringify from a parse interceptor to the watcher
1 parent 77d8ae1 commit 8452a54

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

src/ng/interpolate.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ function $InterpolateProvider() {
202202
}
203203
exp = text.substring(startIndex + startSymbolLength, endIndex);
204204
expressions.push(exp);
205-
parseFns.push($parse(exp, parseStringifyInterceptor));
205+
parseFns.push($parse(exp));
206206
index = endIndex + endSymbolLength;
207207
expressionPositions.push(concat.length);
208208
concat.push('');
@@ -232,7 +232,7 @@ function $InterpolateProvider() {
232232
var compute = function(values) {
233233
for (var i = 0, ii = expressions.length; i < ii; i++) {
234234
if (allOrNothing && isUndefined(values[i])) return;
235-
concat[expressionPositions[i]] = values[i];
235+
concat[expressionPositions[i]] = parseStringifyValue(values[i]);
236236
}
237237
return concat.join('');
238238
};
@@ -282,10 +282,10 @@ function $InterpolateProvider() {
282282
exp: text, //just for compatibility with regular watchers created via $watch
283283
expressions: expressions,
284284
$$watchDelegate: function(scope, listener, objectEquality) {
285-
var lastValue;
285+
var lastValue = NaN;
286286
return scope.$watchGroup(parseFns, function interpolateFnWatcher(values, oldValues) {
287287
var currValue = compute(values);
288-
if (isFunction(listener)) {
288+
if (isFunction(listener) && currValue !== lastValue) {
289289
listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);
290290
}
291291
lastValue = currValue;
@@ -299,7 +299,7 @@ function $InterpolateProvider() {
299299
replace(escapedEndRegexp, endSymbol);
300300
}
301301

302-
function parseStringifyInterceptor(value) {
302+
function parseStringifyValue(value) {
303303
try {
304304
return stringify(getValue(value));
305305
} catch (err) {

test/ng/interpolateSpec.js

+26
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,32 @@ describe('$interpolate', function() {
248248
}));
249249
});
250250

251+
describe("watching", function() {
252+
it("should invoke only on change of output", inject(function($interpolate, $rootScope) {
253+
var watcherInvoked = 0;
254+
$rootScope.a = $rootScope.b = $rootScope.c = 0;
255+
$rootScope.$watch($interpolate("{{a + b}} {{c}}"), function() { watcherInvoked++; });
256+
$rootScope.$apply();
257+
expect(watcherInvoked).toBe(1);
258+
259+
$rootScope.a = 1;
260+
$rootScope.$apply();
261+
expect(watcherInvoked).toBe(2);
262+
263+
$rootScope.a = 0;
264+
$rootScope.b = 1;
265+
$rootScope.$apply();
266+
expect(watcherInvoked).toBe(2);
267+
268+
$rootScope.c = '0';
269+
$rootScope.$apply();
270+
expect(watcherInvoked).toBe(2);
271+
272+
$rootScope.c = {toJSON: function() { return 0; }};
273+
$rootScope.$apply();
274+
expect(watcherInvoked).toBe(2);
275+
}));
276+
});
251277

252278
describe('isTrustedContext', function() {
253279
it('should NOT interpolate a multi-part expression when isTrustedContext is true', inject(function($interpolate) {

0 commit comments

Comments
 (0)