refactor(i18n): I18nPipe uses NgLocalization (#9313)

and some refactoring
This commit is contained in:
Victor Berchet
2016-06-23 11:44:05 -07:00
committed by GitHub
parent 54dbed4f48
commit fed1672a43
11 changed files with 76 additions and 81 deletions

View File

@ -15,7 +15,7 @@ export {CORE_DIRECTIVES} from './directives/core_directives';
export {NgClass} from './directives/ng_class';
export {NgFor} from './directives/ng_for';
export {NgIf} from './directives/ng_if';
export {NgLocalization, NgPlural, NgPluralCase} from './directives/ng_plural';
export {NgPlural, NgPluralCase} from './directives/ng_plural';
export {NgStyle} from './directives/ng_style';
export {NgSwitch, NgSwitchCase, NgSwitchDefault} from './directives/ng_switch';
export {NgTemplateOutlet} from './directives/ng_template_outlet';

View File

@ -7,19 +7,10 @@
*/
import {AfterContentInit, Attribute, ContentChildren, Directive, Input, QueryList, TemplateRef, ViewContainerRef} from '@angular/core';
import {Map} from '../facade/collection';
import {NumberWrapper, isPresent} from '../facade/lang';
import {isPresent} from '../facade/lang';
import {NgLocalization, getPluralCategory} from '../localization';
import {SwitchView} from './ng_switch';
const _CATEGORY_DEFAULT = 'other';
/**
* @experimental
*/
export abstract class NgLocalization { abstract getPluralCategory(value: any): string; }
/**
* `ngPlural` is an i18n directive that displays DOM sub-trees that match the switch expression
* value, or failing that, DOM sub-trees that match the switch expression's pluralization category.
@ -35,9 +26,6 @@ export abstract class NgLocalization { abstract getPluralCategory(value: any): s
* value matches aren't found and the value maps to its category using the `getPluralCategory`
* function provided.
*
* If no matching views are found for a switch expression, inner elements marked
* `[ngPluralCase]="other"` will be displayed.
*
* ```typescript
* class MyLocalization extends NgLocalization {
* getPluralCategory(value: any) {
@ -88,7 +76,6 @@ export class NgPluralCase {
}
}
/**
* @experimental
*/
@ -96,7 +83,7 @@ export class NgPluralCase {
export class NgPlural implements AfterContentInit {
private _switchValue: number;
private _activeView: SwitchView;
private _caseViews = new Map<any, SwitchView>();
private _caseViews: {[k: string]: SwitchView} = {};
@ContentChildren(NgPluralCase) cases: QueryList<NgPluralCase> = null;
constructor(private _localization: NgLocalization) {}
@ -109,7 +96,7 @@ export class NgPlural implements AfterContentInit {
ngAfterContentInit() {
this.cases.forEach((pluralCase: NgPluralCase): void => {
this._caseViews.set(this._formatValue(pluralCase), pluralCase._view);
this._caseViews[pluralCase.value] = pluralCase._view;
});
this._updateView();
}
@ -118,10 +105,9 @@ export class NgPlural implements AfterContentInit {
_updateView(): void {
this._clearViews();
var view: SwitchView = this._caseViews.get(this._switchValue);
if (!isPresent(view)) view = this._getCategoryView(this._switchValue);
this._activateView(view);
var key = getPluralCategory(
this._switchValue, Object.getOwnPropertyNames(this._caseViews), this._localization);
this._activateView(this._caseViews[key]);
}
/** @internal */
@ -135,22 +121,4 @@ export class NgPlural implements AfterContentInit {
this._activeView = view;
this._activeView.create();
}
/** @internal */
_getCategoryView(value: number): SwitchView {
var category: string = this._localization.getPluralCategory(value);
var categoryView: SwitchView = this._caseViews.get(category);
return isPresent(categoryView) ? categoryView : this._caseViews.get(_CATEGORY_DEFAULT);
}
/** @internal */
_isValueView(pluralCase: NgPluralCase): boolean { return pluralCase.value[0] === '='; }
/** @internal */
_formatValue(pluralCase: NgPluralCase): any {
return this._isValueView(pluralCase) ? this._stripValue(pluralCase.value) : pluralCase.value;
}
/** @internal */
_stripValue(value: string): number { return NumberWrapper.parseInt(value.substring(1), 10); }
}

View File

@ -0,0 +1,18 @@
/**
* @experimental
*/
export abstract class NgLocalization { abstract getPluralCategory(value: any): string; }
/**
* Returns the plural category for a given value.
* - "=value" when the case exists,
* - the plural category otherwise
*
* @internal
*/
export function getPluralCategory(
value: number, cases: string[], ngLocalization: NgLocalization): string {
const nbCase = `=${value}`;
return cases.indexOf(nbCase) > -1 ? nbCase : ngLocalization.getPluralCategory(value);
}

View File

@ -7,22 +7,21 @@
*/
import {Pipe, PipeTransform} from '@angular/core';
import {StringWrapper, isPresent, isStringMap} from '../facade/lang';
import {StringWrapper, isBlank, isStringMap} from '../facade/lang';
import {NgLocalization, getPluralCategory} from '../localization';
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
const _INTERPOLATION_REGEXP: RegExp = /#/g;
/**
*
* Maps a value to a string that pluralizes the value properly.
*
* ## Usage
*
* expression | i18nPlural:mapping
*
* where `expression` is a number and `mapping` is an object that indicates the proper text for
* when the `expression` evaluates to 0, 1, or some other number. You can interpolate the actual
* value into the text using the `#` sign.
* where `expression` is a number and `mapping` is an object that mimics the ICU format,
* see http://userguide.icu-project.org/formatparse/messages
*
* ## Example
*
@ -33,7 +32,7 @@ const _INTERPOLATION_REGEXP: RegExp = /#/g;
*
* class MyApp {
* messages: any[];
* messageMapping: any = {
* messageMapping: {[k:string]: string} = {
* '=0': 'No messages.',
* '=1': 'One message.',
* 'other': '# messages.'
@ -46,17 +45,17 @@ const _INTERPOLATION_REGEXP: RegExp = /#/g;
*/
@Pipe({name: 'i18nPlural', pure: true})
export class I18nPluralPipe implements PipeTransform {
constructor(private _localization: NgLocalization) {}
transform(value: number, pluralMap: {[count: string]: string}): string {
var key: string;
var valueStr: string;
if (isBlank(value)) return '';
if (!isStringMap(pluralMap)) {
throw new InvalidPipeArgumentException(I18nPluralPipe, pluralMap);
}
key = value === 0 || value === 1 ? `=${value}` : 'other';
valueStr = isPresent(value) ? value.toString() : '';
const key = getPluralCategory(value, Object.getOwnPropertyNames(pluralMap), this._localization);
return StringWrapper.replaceAll(pluralMap[key], _INTERPOLATION_REGEXP, valueStr);
return StringWrapper.replaceAll(pluralMap[key], _INTERPOLATION_REGEXP, value.toString());
}
}

View File

@ -7,11 +7,9 @@
*/
import {Pipe, PipeTransform} from '@angular/core';
import {StringMapWrapper} from '../facade/collection';
import {isStringMap} from '../facade/lang';
import {isBlank, isStringMap} from '../facade/lang';
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
/**
*
* Generic selector that displays the string that matches the current value.
@ -46,10 +44,12 @@ import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
@Pipe({name: 'i18nSelect', pure: true})
export class I18nSelectPipe implements PipeTransform {
transform(value: string, mapping: {[key: string]: string}): string {
if (isBlank(value)) return '';
if (!isStringMap(mapping)) {
throw new InvalidPipeArgumentException(I18nSelectPipe, mapping);
}
return StringMapWrapper.contains(mapping, value) ? mapping[value] : mapping['other'];
return mapping.hasOwnProperty(value) ? mapping[value] : '';
}
}