| OLD | NEW |
| 1 part of angular.directive; | 1 part of angular.directive; |
| 2 | 2 |
| 3 /** | 3 /** |
| 4 * ## Overview | 4 * ## Overview |
| 5 * `ngPluralize` is a directive that displays messages according to locale rules
. | 5 * `ngPluralize` is a directive that displays messages according to locale rules
. |
| 6 * | 6 * |
| 7 * You configure ngPluralize directive by specifying the mappings between plural | 7 * You configure ngPluralize directive by specifying the mappings between plural |
| 8 * categories and the strings to be displayed. | 8 * categories and the strings to be displayed. |
| 9 * | 9 * |
| 10 * ## Plural categories and explicit number rules | 10 * ## Plural categories and explicit number rules |
| 11 * The available plural categories are: | 11 * The available plural categories are: |
| 12 * * "zero", | 12 * * "zero", |
| 13 * * "one", | 13 * * "one", |
| 14 * * "two", | 14 * * "two", |
| 15 * * "few", | 15 * * "few", |
| 16 * * "many", | 16 * * "many", |
| 17 * * "other". | 17 * * "other". |
| 18 * | 18 * |
| 19 * While a plural category may match many numbers, an explicit number rule can | 19 * While a plural category may match many numbers, an explicit number rule can o
nly match |
| 20 * only match one number. For example, the explicit number rule for "3" matches | 20 * one number. For example, the explicit number rule for "3" matches the number
3. There |
| 21 * the number 3. There are examples of plural categories and explicit number | 21 * are examples of plural categories and explicit number rules throughout the re
st of this |
| 22 * rules throughout the rest of this documentation. | 22 * documentation. |
| 23 * | 23 * |
| 24 * ## Configuring ngPluralize | 24 * ## Configuring ngPluralize |
| 25 * You configure ngPluralize by providing 2 attributes: `count` and `when`. | 25 * You configure ngPluralize by providing 2 attributes: `count` and `when`. |
| 26 * You can also provide an optional attribute, `offset`. | 26 * You can also provide an optional attribute, `offset`. |
| 27 * | 27 * |
| 28 * The value of the `count` attribute can be either a string or an expression; | 28 * The value of the `count` attribute can be either a string or an expression; t
hese are |
| 29 * these are evaluated on the current scope for its bound value. | 29 * evaluated on the current scope for its bound value. |
| 30 * | 30 * |
| 31 * The `when` attribute specifies the mappings between plural categories and the | 31 * The `when` attribute specifies the mappings between plural categories and the
actual |
| 32 * actual string to be displayed. The value of the attribute should be a JSON | 32 * string to be displayed. The value of the attribute should be a JSON object. |
| 33 * object. | |
| 34 * | 33 * |
| 35 * The following example shows how to configure ngPluralize: | 34 * The following example shows how to configure ngPluralize: |
| 36 * | 35 * |
| 37 * <ng-pluralize count="personCount" | 36 * <ng-pluralize count="personCount" |
| 38 * when="{'0': 'Nobody is viewing.', | 37 * when="{'0': 'Nobody is viewing.', |
| 39 * 'one': '1 person is viewing.', | 38 * 'one': '1 person is viewing.', |
| 40 * 'other': '{} people are viewing.'}"> | 39 * 'other': '{} people are viewing.'}"> |
| 41 * </ng-pluralize> | 40 * </ng-pluralize> |
| 42 * | 41 * |
| 43 * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you | 42 * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you
did not |
| 44 * did not specify this rule, 0 would be matched to the "other" category and | 43 * specify this rule, 0 would be matched to the "other" category and "0 people a
re viewing" |
| 45 * "0 people are viewing" would be shown instead of "Nobody is viewing". You can | 44 * would be shown instead of "Nobody is viewing". You can specify an explicit nu
mber rule for |
| 46 * specify an explicit number rule for other numbers, for example 12, so that | 45 * other numbers, for example 12, so that instead of showing "12 people are view
ing", you can |
| 47 * instead of showing "12 people are viewing", you can show "a dozen people are | 46 * show "a dozen people are viewing". |
| 48 * viewing". | |
| 49 * | 47 * |
| 50 * You can use a set of closed braces (`{}`) as a placeholder for the number | 48 * You can use a set of closed braces (`{}`) as a placeholder for the number tha
t you want substituted |
| 51 * that you want substituted into pluralized strings. In the previous example, | 49 * into pluralized strings. In the previous example, Angular will replace `{}` w
ith |
| 52 * Angular will replace `{}` with `{{personCount}}`. The closed braces `{}` is a | 50 * `{{personCount}}`. The closed braces `{}` is a placeholder {{numberExpression
}}. |
| 53 * placeholder {{numberExpression}}. | |
| 54 * | 51 * |
| 55 * ## Configuring ngPluralize with offset | 52 * ## Configuring ngPluralize with offset |
| 56 * The `offset` attribute allows further customization of pluralized text, which | 53 * The `offset` attribute allows further customization of pluralized text, which
can result in |
| 57 * can result in a better user experience. For example, instead of the message | 54 * a better user experience. For example, instead of the message "4 people are v
iewing this document", |
| 58 * "4 people are viewing this document", you might display "John, Kate and 2 | 55 * you might display "John, Kate and 2 others are viewing this document". |
| 59 * others are viewing this document". The offset attribute allows you to offset | 56 * The offset attribute allows you to offset a number by any desired value. |
| 60 * a number by any desired value. | |
| 61 * | |
| 62 * Let's take a look at an example: | 57 * Let's take a look at an example: |
| 63 * | 58 * |
| 64 * <ng-pluralize count="personCount" offset=2 | 59 * <ng-pluralize count="personCount" offset=2 |
| 65 * when="{'0': 'Nobody is viewing.', | 60 * when="{'0': 'Nobody is viewing.', |
| 66 * '1': '${person1} is viewing.', | 61 * '1': '{{person1}} is viewing.', |
| 67 * '2': '${person1} and ${person2} are viewing.', | 62 * '2': '{{person1}} and {{person2}} are viewing.', |
| 68 * 'one': '${person1}, ${person2} and one other person a
re viewing.', | 63 * 'one': '{{person1}}, {{person2}} and one other person
are viewing.', |
| 69 * 'other': '${person1}, ${person2} and {} other people
are viewing.'}"> | 64 * 'other': '{{person1}}, {{person2}} and {} other peopl
e are viewing.'}"> |
| 70 * </ng-pluralize> | 65 * </ng-pluralize> |
| 71 * | 66 * |
| 72 * Notice that we are still using two plural categories(one, other), but we adde
d | 67 * Notice that we are still using two plural categories(one, other), but we adde
d |
| 73 * three explicit number rules 0, 1 and 2. | 68 * three explicit number rules 0, 1 and 2. |
| 74 * When one person, perhaps John, views the document, "John is viewing" will be | 69 * When one person, perhaps John, views the document, "John is viewing" will be
shown. |
| 75 * shown. When three people view the document, no explicit number rule is found, | 70 * When three people view the document, no explicit number rule is found, so |
| 76 * so an offset of 2 is taken off 3, and Angular uses 1 to decide the plural | 71 * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural catego
ry. |
| 77 * category. In this case, plural category 'one' is matched and "John, Marry and | 72 * In this case, plural category 'one' is matched and "John, Marry and one other
person are viewing" |
| 78 * one other person are viewing" is shown. | 73 * is shown. |
| 79 * | 74 * |
| 80 * Note that when you specify offsets, you must provide explicit number rules | 75 * Note that when you specify offsets, you must provide explicit number rules fo
r |
| 81 * for numbers from 0 up to and including the offset. If you use an offset of 3, | 76 * numbers from 0 up to and including the offset. If you use an offset of 3, for
example, |
| 82 * for example, you must provide explicit number rules for 0, 1, 2 and 3. You | 77 * you must provide explicit number rules for 0, 1, 2 and 3. You must also provi
de plural strings for |
| 83 * must also provide plural strings for at least the "other" plural category. | 78 * at least the "other" plural category. |
| 84 */ | 79 */ |
| 85 @NgDirective( | 80 @NgDirective( |
| 86 selector: 'ng-pluralize', | 81 selector: 'ng-pluralize', |
| 87 map: const { 'count': '=>count' }) | 82 map: const { 'count': '=>count' }) |
| 88 @NgDirective( | 83 @NgDirective( |
| 89 selector: '[ng-pluralize]', | 84 selector: '[ng-pluralize]', |
| 90 map: const { 'count': '=>count' }) | 85 map: const { 'count': '=>count' }) |
| 91 class NgPluralizeDirective { | 86 class NgPluralizeDirective { |
| 87 |
| 92 final dom.Element element; | 88 final dom.Element element; |
| 93 final Scope scope; | 89 final Scope scope; |
| 94 final Interpolate interpolate; | 90 final Interpolate interpolate; |
| 95 final AstParser parser; | |
| 96 int offset; | 91 int offset; |
| 97 var discreteRules = <String, String>{}; | 92 Map<String, String> discreteRules = new Map(); |
| 98 var categoryRules = <Symbol, String>{}; | 93 Map<Symbol, String> categoryRules = new Map(); |
| 94 static final RegExp IS_WHEN = new RegExp(r'^when-(minus-)?.'); |
| 99 | 95 |
| 100 static final RegExp IS_WHEN = new RegExp(r'^when-(minus-)?.'); | 96 NgPluralizeDirective(this.scope, this.element, this.interpolate, NodeAttrs att
ributes) { |
| 101 static const Map<String, Symbol> SYMBOLS = const { | 97 Map<String, String> whens = attributes['when'] == null ? {} : scope.$eval(at
tributes['when']); |
| 102 'zero' : #zero, | |
| 103 'one' : #one, | |
| 104 'two' : #two, | |
| 105 'few' : #few, | |
| 106 'many' : #many, | |
| 107 'other' : #other, | |
| 108 }; | |
| 109 | |
| 110 NgPluralizeDirective(this.scope, this.element, this.interpolate, | |
| 111 NodeAttrs attributes, this.parser) { | |
| 112 Map<String, String> whens = attributes['when'] == null | |
| 113 ? {} | |
| 114 : scope.eval(attributes['when']); | |
| 115 offset = attributes['offset'] == null ? 0 : int.parse(attributes['offset']); | 98 offset = attributes['offset'] == null ? 0 : int.parse(attributes['offset']); |
| 116 | 99 |
| 117 element.attributes.keys.where((k) => IS_WHEN.hasMatch(k)).forEach((k) { | 100 element.attributes.keys.where((k) => IS_WHEN.hasMatch(k)).forEach((k) { |
| 118 var ruleName = k.replaceFirst('when-', '').replaceFirst('minus-', '-'); | 101 var ruleName = k.replaceFirst('when-', '').replaceFirst('minus-', '-'); |
| 119 whens[ruleName] = element.attributes[k]; | 102 whens[ruleName] = element.attributes[k]; |
| 120 }); | 103 }); |
| 121 | 104 |
| 122 if (whens['other'] == null) { | 105 if (whens['other'] == null) { |
| 123 throw "ngPluralize error! The 'other' plural category must always be " | 106 throw "ngPluralize error! The 'other' plural category must always be speci
fied"; |
| 124 "specified"; | |
| 125 } | 107 } |
| 126 | 108 |
| 127 whens.forEach((k, v) { | 109 whens.forEach((k, v) { |
| 128 Symbol symbol = SYMBOLS[k]; | 110 if (['zero', 'one', 'two', 'few', 'many', 'other'].contains(k)) { |
| 129 if (symbol != null) { | 111 this.categoryRules[new Symbol(k.toString())] = v; |
| 130 this.categoryRules[symbol] = v; | |
| 131 } else { | 112 } else { |
| 132 this.discreteRules[k] = v; | 113 this.discreteRules[k.toString()] = v; |
| 133 } | 114 } |
| 134 }); | 115 }); |
| 135 } | 116 } |
| 136 | 117 |
| 137 set count(value) { | 118 set count(value) { |
| 138 if (value is! num) { | 119 if (value is! num) { |
| 139 try { | 120 try { |
| 140 value = int.parse(value); | 121 value = int.parse(value); |
| 141 } catch(e) { | 122 } catch(e) { |
| 142 try { | 123 try { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 157 intValue -= offset; | 138 intValue -= offset; |
| 158 var exp = Function.apply(Intl.plural, [intValue], categoryRules); | 139 var exp = Function.apply(Intl.plural, [intValue], categoryRules); |
| 159 if (exp != null) { | 140 if (exp != null) { |
| 160 exp = exp.replaceAll(r'{}', (value - offset).toString()); | 141 exp = exp.replaceAll(r'{}', (value - offset).toString()); |
| 161 _setAndWatch(exp); | 142 _setAndWatch(exp); |
| 162 } | 143 } |
| 163 } | 144 } |
| 164 } | 145 } |
| 165 | 146 |
| 166 _setAndWatch(expression) { | 147 _setAndWatch(expression) { |
| 167 var interpolation = interpolate(expression, false, '\${', '}'); | 148 Interpolation interpolation = interpolate(expression); |
| 168 interpolation.setter = (text) => element.text = text; | 149 interpolation.setter = (text) => element.text = text; |
| 169 interpolation.setter(expression); | 150 interpolation.setter(expression); |
| 170 var items = interpolation.expressions.map((exp) => parser(exp)).toList(); | 151 scope.$watchSet(interpolation.watchExpressions, interpolation.call); |
| 171 AST ast = new PureFunctionAST(expression, new ArrayFn(), items); | |
| 172 scope.watch(ast, interpolation.call); | |
| 173 } | 152 } |
| 174 } | 153 } |
| OLD | NEW |