Skip to content

Commit

Permalink
test($interpolate): add a test to address Igor's first concern
Browse files Browse the repository at this point in the history
which is point angular#1 in this PR comment angular#4556 (comment)
also merged Igor's first code review IgorMinar@784dd4e
  • Loading branch information
rodyhaddad committed Dec 19, 2013
1 parent 33de609 commit 2338fd7
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 14 deletions.
31 changes: 18 additions & 13 deletions src/ng/interpolate.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,57 +169,62 @@ function $InterpolateProvider() {
if (!mustHaveExpression || hasInterpolation) {
var concat = new Array(parts.length),
expressions = {};
forEach(parts, function (value, index) {

forEach(parts, function(value, index) {
if (isFunction(value)) {
expressions[index] = value;
concat[index] = '';
} else {
concat[index] = value;
}
});

// computes all the interpolations and returns the resulting string
// a specific index might already be computed (cz of the scope's dirty-checking),
// a specific index might already be computed (thanks to the scope's dirty-checking),
// and so its expression shouldn't be executed a 2nd time
// also populates the lastValues of custom watchers for internal dirty-checking
var getTextValue = function (scope, computedIndex, computedValue, lastValues) {
var getConcatValue = function(scope, computedIndex, computedValue, lastValues) {
try {
forEach(expressions, function (expression, index) {
concat[index] = index == computedIndex

forEach(expressions, function(expression, index) {
concat[index] = (index === computedIndex)
? computedValue
: getStringValue(expression(scope));

if (lastValues) lastValues[index] = concat[index];
});
return concat.join('');
}
catch(err) {

} catch(err) {
var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
err.toString());
$exceptionHandler(newErr);
}
};
var getStringValue = function (value) {

var getStringValue = function(value) {
value = trustedContext
? $sce.getTrusted(trustedContext, value)
: $sce.valueOf(value);

if (value === null || isUndefined(value)) {
if (value == null) {
return '';
}
return isString(value) ? value : toJson(value);
};

fn = function(scope) {
return getTextValue(scope);
// we don't want others to be able to pass more than the first argument
return getConcatValue(scope);
};
fn.exp = text;
fn.parts = parts;

// watches each interpolation separately for performance
fn.$$beWatched = function (scope, origListener, objectEquality) {
fn.$$beWatched = function(scope, origListener, objectEquality) {
var lastTextValue, lastValues = {}, watchersRm = [];

forEach(expressions, function (expression, index) {
forEach(expressions, function(expression, index) {
watchersRm.push(scope.$watch(function watchInterpolatedExpr(scope) {
try {
return getStringValue(expression(scope));
Expand All @@ -241,7 +246,7 @@ function $InterpolateProvider() {
// and ignore it when the listener of `b` gets triggered
// (unless the value of `b` changes again since the last computation)
if (value !== lastValues[index]) {
var textValue = getTextValue(scope, index, value, lastValues);
var textValue = getConcatValue(scope, index, value, lastValues);
origListener.call(this, textValue,
value === oldValue ? textValue : lastTextValue, scope);
lastTextValue = textValue;
Expand Down
37 changes: 36 additions & 1 deletion test/ng/interpolateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,41 @@ describe('$interpolate', function() {
});
expect(nbCalls).toBe(4);
}));
})

it('should call the listener only once per whole text change', inject(function ($rootScope, $interpolate) {
var nbCalls = 0, value;
$rootScope.$watch($interpolate("{{a}}-{{b}}"), function (_value){
nbCalls++;
value = _value;
});

$rootScope.$apply();
expect(nbCalls).toBe(1);
expect(value).toBe('-');

$rootScope.$apply('a=1;b=1');
expect(nbCalls).toBe(2);
expect(value).toBe('1-1');

// one changes
$rootScope.$apply('a=2');
expect(nbCalls).toBe(3);
expect(value).toBe('2-1');

$rootScope.$apply('b=2');
expect(nbCalls).toBe(4);
expect(value).toBe('2-2');

// both change
$rootScope.$apply('a=3;b=3');
expect(nbCalls).toBe(5);
expect(value).toBe('3-3');

// nothing changes
$rootScope.$apply();
expect(nbCalls).toBe(5);
expect(value).toBe('3-3');
}));
});

});

0 comments on commit 2338fd7

Please sign in to comment.