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

Commit 3b5751d

Browse files
committed
fix($parse): call once stable bind-once expressions with filter
When an expression has the following: - Bind-once - A stateless filter at the end - Optionally an expression interceptor Then call the filter once. Closes: #14583 Closes: #14589
1 parent 5d1e15c commit 3b5751d

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

src/ng/parse.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,14 +2050,20 @@ function $ParseProvider() {
20502050
}, listener, objectEquality, prettyPrintExpression);
20512051
}
20522052

2053-
function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression) {
2053+
function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {
20542054
var unwatch, lastValue;
2055-
return unwatch = scope.$watch(function oneTimeWatch(scope) {
2055+
if (parsedExpression.inputs) {
2056+
return unwatch = inputsWatchDelegate(scope, oneTimeListener, objectEquality, parsedExpression, prettyPrintExpression);
2057+
} else {
2058+
return unwatch = scope.$watch(oneTimeWatch, oneTimeListener, objectEquality);
2059+
}
2060+
function oneTimeWatch(scope) {
20562061
return parsedExpression(scope);
2057-
}, function oneTimeListener(value, old, scope) {
2062+
}
2063+
function oneTimeListener(value, old, scope) {
20582064
lastValue = value;
20592065
if (isFunction(listener)) {
2060-
listener.apply(this, arguments);
2066+
listener(value, old, scope);
20612067
}
20622068
if (isDefined(value)) {
20632069
scope.$$postDigest(function() {
@@ -2066,7 +2072,7 @@ function $ParseProvider() {
20662072
}
20672073
});
20682074
}
2069-
}, objectEquality);
2075+
}
20702076
}
20712077

20722078
function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {
@@ -2076,7 +2082,7 @@ function $ParseProvider() {
20762082
}, function oneTimeListener(value, old, scope) {
20772083
lastValue = value;
20782084
if (isFunction(listener)) {
2079-
listener.call(this, value, old, scope);
2085+
listener(value, old, scope);
20802086
}
20812087
if (isAllDefined(value)) {
20822088
scope.$$postDigest(function() {
@@ -2123,14 +2129,15 @@ function $ParseProvider() {
21232129
};
21242130

21252131
// Propagate $$watchDelegates other then inputsWatchDelegate
2132+
useInputs = !parsedExpression.inputs;
21262133
if (parsedExpression.$$watchDelegate &&
21272134
parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
21282135
fn.$$watchDelegate = parsedExpression.$$watchDelegate;
2136+
fn.inputs = parsedExpression.inputs;
21292137
} else if (!interceptorFn.$stateful) {
21302138
// If there is an interceptor, but no watchDelegate then treat the interceptor like
21312139
// we treat filters - it is assumed to be a pure function unless flagged with $stateful
21322140
fn.$$watchDelegate = inputsWatchDelegate;
2133-
useInputs = !parsedExpression.inputs;
21342141
fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression];
21352142
}
21362143

test/ng/parseSpec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3232,6 +3232,18 @@ describe('parser', function() {
32323232
expect(fn()).toEqual(undefined);
32333233
}));
32343234

3235+
it('should invoke a stateless filter once when the parsed expression has an interceptor',
3236+
inject(function($parse, $rootScope) {
3237+
var countFilter = jasmine.createSpy();
3238+
var interceptor = jasmine.createSpy();
3239+
countFilter.and.returnValue(1);
3240+
$filterProvider.register('count', valueFn(countFilter));
3241+
$rootScope.foo = function() { return 1; };
3242+
$rootScope.$watch($parse(':: foo() | count', interceptor));
3243+
$rootScope.$digest();
3244+
expect(countFilter.calls.count()).toBe(1);
3245+
}));
3246+
32353247
describe('literal expressions', function() {
32363248
it('should mark an empty expressions as literal', inject(function($parse) {
32373249
expect($parse('').literal).toBe(true);

0 commit comments

Comments
 (0)