Skip to content
Permalink
Browse files

feat(ngPluralize): add support for `count` to be a one-time expression

Closes #10004
  • Loading branch information...
gkalpak authored and lgalfaso committed Nov 12, 2014
1 parent 637c020 commit 2b41a5868aee79e3872ad92db66e30959207d98e
Showing with 103 additions and 19 deletions.
  1. +31 −19 src/ng/directive/ngPluralize.js
  2. +72 −0 test/ng/directive/ngPluralizeSpec.js
@@ -173,7 +173,9 @@
</example>
*/
var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
var BRACE = /{}/g;
var BRACE = /{}/g,
IS_WHEN = /^when(Minus)?(.+)$/;

return {
restrict: 'EA',
link: function(scope, element, attr) {
@@ -184,34 +186,44 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
whensExpFns = {},
startSymbol = $interpolate.startSymbol(),
endSymbol = $interpolate.endSymbol(),
isWhen = /^when(Minus)?(.+)$/;
braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,
watchRemover = angular.noop,
lastCount;

forEach(attr, function(expression, attributeName) {
if (isWhen.test(attributeName)) {
whens[lowercase(attributeName.replace('when', '').replace('Minus', '-'))] =
element.attr(attr.$attr[attributeName]);
var tmpMatch = IS_WHEN.exec(attributeName);
if (tmpMatch) {
var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);
whens[whenKey] = element.attr(attr.$attr[attributeName]);
}
});
forEach(whens, function(expression, key) {
whensExpFns[key] =
$interpolate(expression.replace(BRACE, startSymbol + numberExp + '-' +
offset + endSymbol));
whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));

});

scope.$watch(function ngPluralizeWatch() {
var value = parseFloat(scope.$eval(numberExp));
scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
var count = parseFloat(newVal);
var countIsNaN = isNaN(count);

if (!isNaN(value)) {
//if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
//check it against pluralization rules in $locale service
if (!(value in whens)) value = $locale.pluralCat(value - offset);
return whensExpFns[value](scope);
} else {
return '';
if (!countIsNaN && !(count in whens)) {
// If an explicit number rule such as 1, 2, 3... is defined, just use it.
// Otherwise, check it against pluralization rules in $locale service.
count = $locale.pluralCat(count - offset);
}

// If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
// In JS `NaN !== NaN`, so we have to exlicitly check.
if ((count !== lastCount) && !(countIsNaN && isNaN(lastCount))) {
watchRemover();
watchRemover = scope.$watch(whensExpFns[count], updateElementText);
lastCount = count;
}
}, function ngPluralizeWatchAction(newVal) {
element.text(newVal);
});

function updateElementText(newText) {
element.text(newText || '');
}
}
};
}];
@@ -242,4 +242,76 @@ describe('ngPluralize', function() {
});
});
});


describe('bind-once', function() {

it('should support for `count` to be a one-time expression',
inject(function($compile, $rootScope) {
element = $compile(
'<ng:pluralize count="::email"' +
"when=\"{'one': 'You have one new email'," +
"'other': 'You have {} new emails'}\">" +
'</ng:pluralize>')($rootScope);
elementAlt = $compile(
'<ng:pluralize count="::email" ' +
"when-one='You have one new email' " +
"when-other='You have {} new emails'>" +
'</ng:pluralize>')($rootScope);

$rootScope.email = undefined;
$rootScope.$digest();
expect(element.text()).toBe('');
expect(elementAlt.text()).toBe('');

$rootScope.email = 3;
$rootScope.$digest();
expect(element.text()).toBe('You have 3 new emails');
expect(elementAlt.text()).toBe('You have 3 new emails');

$rootScope.email = 2;
$rootScope.$digest();
expect(element.text()).toBe('You have 3 new emails');
expect(elementAlt.text()).toBe('You have 3 new emails');

$rootScope.email = 1;
$rootScope.$digest();
expect(element.text()).toBe('You have 3 new emails');
expect(elementAlt.text()).toBe('You have 3 new emails');
})
);


it('should still update other embedded expressions',
inject(function($compile, $rootScope) {
element = $compile(
'<ng:pluralize count="::email"' +
"when=\"{'one': 'You, {{user}}, have one new email'," +
"'other': 'You, {{user}}, have {} new emails'}\">" +
'</ng:pluralize>')($rootScope);
elementAlt = $compile(
'<ng:pluralize count="::email" ' +
"when-one='You, {{user}}, have one new email' " +
"when-other='You, {{user}}, have {} new emails'>" +
'</ng:pluralize>')($rootScope);

$rootScope.user = 'Lucas';
$rootScope.email = undefined;
$rootScope.$digest();
expect(element.text()).toBe('');
expect(elementAlt.text()).toBe('');

$rootScope.email = 3;
$rootScope.$digest();
expect(element.text()).toBe('You, Lucas, have 3 new emails');
expect(elementAlt.text()).toBe('You, Lucas, have 3 new emails');

$rootScope.user = 'Pete';
$rootScope.email = 2;
$rootScope.$digest();
expect(element.text()).toBe('You, Pete, have 3 new emails');
expect(elementAlt.text()).toBe('You, Pete, have 3 new emails');
})
);
});
});

0 comments on commit 2b41a58

Please sign in to comment.
You can’t perform that action at this time.