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