2016-06-23 09:47:54 -07:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
2016-09-08 19:25:25 -07:00
|
|
|
import {Attribute, Directive, Host, Input, TemplateRef, ViewContainerRef} from '@angular/core';
|
2016-07-07 14:47:06 -07:00
|
|
|
|
2016-06-23 11:44:05 -07:00
|
|
|
import {NgLocalization, getPluralCategory} from '../localization';
|
2016-07-07 14:47:06 -07:00
|
|
|
|
2016-03-04 16:32:22 -08:00
|
|
|
import {SwitchView} from './ng_switch';
|
|
|
|
|
2016-07-07 14:47:06 -07:00
|
|
|
|
2016-03-04 16:32:22 -08:00
|
|
|
/**
|
2016-09-12 10:20:33 -07:00
|
|
|
* @ngModule CommonModule
|
2016-03-04 16:32:22 -08:00
|
|
|
*
|
2016-09-12 10:20:33 -07:00
|
|
|
* @whatItDoes Adds / removes DOM sub-trees based on a numeric value. Tailored for pluralization.
|
|
|
|
*
|
|
|
|
* @howToUse
|
|
|
|
* ```
|
|
|
|
* <some-element [ngPlural]="value">
|
|
|
|
* <ng-container *ngPluralCase="'=0'">there is nothing</ng-container>
|
|
|
|
* <ng-container *ngPluralCase="'=1'">there is one</ng-container>
|
|
|
|
* <ng-container *ngPluralCase="'few'">there are a few</ng-container>
|
|
|
|
* <ng-container *ngPluralCase="'other'">there are exactly #</ng-container>
|
|
|
|
* </some-element>
|
|
|
|
* ```
|
2016-03-04 16:32:22 -08:00
|
|
|
*
|
2016-09-12 10:20:33 -07:00
|
|
|
* @description
|
2016-03-04 16:32:22 -08:00
|
|
|
*
|
2016-09-12 10:20:33 -07:00
|
|
|
* Displays DOM sub-trees that match the switch expression value, or failing that, DOM sub-trees
|
|
|
|
* that match the switch expression's pluralization category.
|
2016-03-04 16:32:22 -08:00
|
|
|
*
|
2016-09-12 10:20:33 -07:00
|
|
|
* To use this directive you must provide a container element that sets the `[ngPlural]` attribute
|
|
|
|
* to a switch expression. Inner elements with a `[ngPluralCase]` will display based on their
|
|
|
|
* expression:
|
|
|
|
* - if `[ngPluralCase]` is set to a value starting with `=`, it will only display if the value
|
|
|
|
* matches the switch expression exactly,
|
|
|
|
* - otherwise, the view will be treated as a "category match", and will only display if exact
|
|
|
|
* value matches aren't found and the value maps to its category for the defined locale.
|
|
|
|
*
|
|
|
|
* See http://cldr.unicode.org/index/cldr-spec/plural-rules
|
2016-03-04 16:32:22 -08:00
|
|
|
*
|
2016-05-27 11:24:05 -07:00
|
|
|
* @experimental
|
2016-03-04 16:32:22 -08:00
|
|
|
*/
|
|
|
|
@Directive({selector: '[ngPlural]'})
|
2016-07-07 14:47:06 -07:00
|
|
|
export class NgPlural {
|
2016-03-04 16:32:22 -08:00
|
|
|
private _switchValue: number;
|
|
|
|
private _activeView: SwitchView;
|
2016-06-23 11:44:05 -07:00
|
|
|
private _caseViews: {[k: string]: SwitchView} = {};
|
2016-03-04 16:32:22 -08:00
|
|
|
|
|
|
|
constructor(private _localization: NgLocalization) {}
|
|
|
|
|
|
|
|
@Input()
|
|
|
|
set ngPlural(value: number) {
|
|
|
|
this._switchValue = value;
|
|
|
|
this._updateView();
|
|
|
|
}
|
|
|
|
|
2016-07-07 14:47:06 -07:00
|
|
|
addCase(value: string, switchView: SwitchView): void { this._caseViews[value] = switchView; }
|
2016-03-04 16:32:22 -08:00
|
|
|
|
2016-09-22 10:34:00 -07:00
|
|
|
private _updateView(): void {
|
2016-03-04 16:32:22 -08:00
|
|
|
this._clearViews();
|
|
|
|
|
2016-09-08 19:25:25 -07:00
|
|
|
const cases = Object.keys(this._caseViews);
|
|
|
|
const key = getPluralCategory(this._switchValue, cases, this._localization);
|
2016-06-23 11:44:05 -07:00
|
|
|
this._activateView(this._caseViews[key]);
|
2016-03-04 16:32:22 -08:00
|
|
|
}
|
|
|
|
|
2016-09-22 10:34:00 -07:00
|
|
|
private _clearViews() {
|
2016-09-08 19:25:25 -07:00
|
|
|
if (this._activeView) this._activeView.destroy();
|
2016-03-04 16:32:22 -08:00
|
|
|
}
|
|
|
|
|
2016-09-22 10:34:00 -07:00
|
|
|
private _activateView(view: SwitchView) {
|
2016-09-08 19:25:25 -07:00
|
|
|
if (view) {
|
|
|
|
this._activeView = view;
|
|
|
|
this._activeView.create();
|
|
|
|
}
|
2016-03-04 16:32:22 -08:00
|
|
|
}
|
|
|
|
}
|
2016-07-07 14:47:06 -07:00
|
|
|
|
|
|
|
/**
|
2016-09-12 10:20:33 -07:00
|
|
|
* @ngModule CommonModule
|
|
|
|
*
|
|
|
|
* @whatItDoes Creates a view that will be added/removed from the parent {@link NgPlural} when the
|
|
|
|
* given expression matches the plural expression according to CLDR rules.
|
|
|
|
*
|
|
|
|
* @howToUse
|
2016-09-15 09:09:00 -07:00
|
|
|
* ```
|
|
|
|
* <some-element [ngPlural]="value">
|
|
|
|
* <ng-container *ngPluralCase="'=0'">...</ng-container>
|
|
|
|
* <ng-container *ngPluralCase="'other'">...</ng-container>
|
|
|
|
* </some-element>
|
|
|
|
*```
|
2016-09-12 10:20:33 -07:00
|
|
|
*
|
|
|
|
* See {@link NgPlural} for more details and example.
|
|
|
|
*
|
2016-07-07 14:47:06 -07:00
|
|
|
* @experimental
|
|
|
|
*/
|
|
|
|
@Directive({selector: '[ngPluralCase]'})
|
|
|
|
export class NgPluralCase {
|
|
|
|
constructor(
|
|
|
|
@Attribute('ngPluralCase') public value: string, template: TemplateRef<Object>,
|
|
|
|
viewContainer: ViewContainerRef, @Host() ngPlural: NgPlural) {
|
|
|
|
ngPlural.addCase(value, new SwitchView(viewContainer, template));
|
|
|
|
}
|
|
|
|
}
|