refactor(common): pipe code cleanup
This commit is contained in:
parent
70488ed382
commit
5509453e72
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
import {ChangeDetectorRef, OnDestroy, Pipe, WrappedValue} from '@angular/core';
|
import {ChangeDetectorRef, OnDestroy, Pipe, WrappedValue} from '@angular/core';
|
||||||
import {EventEmitter, Observable} from '../facade/async';
|
import {EventEmitter, Observable} from '../facade/async';
|
||||||
import {isBlank, isPresent} from '../facade/lang';
|
|
||||||
import {isPromise} from '../private_import_core';
|
import {isPromise} from '../private_import_core';
|
||||||
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
@ -38,9 +37,8 @@ class PromiseStrategy implements SubscriptionStrategy {
|
|||||||
onDestroy(subscription: any): void {}
|
onDestroy(subscription: any): void {}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _promiseStrategy = new PromiseStrategy();
|
const _promiseStrategy = new PromiseStrategy();
|
||||||
var _observableStrategy = new ObservableStrategy();
|
const _observableStrategy = new ObservableStrategy();
|
||||||
var __unused: Promise<any>; // avoid unused import when Promise union types are erased
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngModule CommonModule
|
* @ngModule CommonModule
|
||||||
@ -69,30 +67,24 @@ var __unused: Promise<any>; // avoid unused import when Promise union types are
|
|||||||
*/
|
*/
|
||||||
@Pipe({name: 'async', pure: false})
|
@Pipe({name: 'async', pure: false})
|
||||||
export class AsyncPipe implements OnDestroy {
|
export class AsyncPipe implements OnDestroy {
|
||||||
/** @internal */
|
private _latestValue: Object = null;
|
||||||
_latestValue: Object = null;
|
private _latestReturnedValue: Object = null;
|
||||||
/** @internal */
|
|
||||||
_latestReturnedValue: Object = null;
|
|
||||||
|
|
||||||
/** @internal */
|
private _subscription: Object = null;
|
||||||
_subscription: Object = null;
|
private _obj: Observable<any>|Promise<any>|EventEmitter<any> = null;
|
||||||
/** @internal */
|
|
||||||
_obj: Observable<any>|Promise<any>|EventEmitter<any> = null;
|
|
||||||
/** @internal */
|
|
||||||
_ref: ChangeDetectorRef;
|
|
||||||
private _strategy: SubscriptionStrategy = null;
|
private _strategy: SubscriptionStrategy = null;
|
||||||
|
|
||||||
constructor(_ref: ChangeDetectorRef) { this._ref = _ref; }
|
constructor(private _ref: ChangeDetectorRef) {}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
if (isPresent(this._subscription)) {
|
if (this._subscription) {
|
||||||
this._dispose();
|
this._dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transform(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
|
transform(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
|
||||||
if (isBlank(this._obj)) {
|
if (!this._obj) {
|
||||||
if (isPresent(obj)) {
|
if (obj) {
|
||||||
this._subscribe(obj);
|
this._subscribe(obj);
|
||||||
}
|
}
|
||||||
this._latestReturnedValue = this._latestValue;
|
this._latestReturnedValue = this._latestValue;
|
||||||
@ -106,33 +98,32 @@ export class AsyncPipe implements OnDestroy {
|
|||||||
|
|
||||||
if (this._latestValue === this._latestReturnedValue) {
|
if (this._latestValue === this._latestReturnedValue) {
|
||||||
return this._latestReturnedValue;
|
return this._latestReturnedValue;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
this._latestReturnedValue = this._latestValue;
|
this._latestReturnedValue = this._latestValue;
|
||||||
return WrappedValue.wrap(this._latestValue);
|
return WrappedValue.wrap(this._latestValue);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** @internal */
|
private _subscribe(obj: Observable<any>|Promise<any>|EventEmitter<any>): void {
|
||||||
_subscribe(obj: Observable<any>|Promise<any>|EventEmitter<any>): void {
|
|
||||||
this._obj = obj;
|
this._obj = obj;
|
||||||
this._strategy = this._selectStrategy(obj);
|
this._strategy = this._selectStrategy(obj);
|
||||||
this._subscription = this._strategy.createSubscription(
|
this._subscription = this._strategy.createSubscription(
|
||||||
obj, (value: Object) => this._updateLatestValue(obj, value));
|
obj, (value: Object) => this._updateLatestValue(obj, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
private _selectStrategy(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
|
||||||
_selectStrategy(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
|
|
||||||
if (isPromise(obj)) {
|
if (isPromise(obj)) {
|
||||||
return _promiseStrategy;
|
return _promiseStrategy;
|
||||||
} else if ((<any>obj).subscribe) {
|
|
||||||
return _observableStrategy;
|
|
||||||
} else {
|
|
||||||
throw new InvalidPipeArgumentError(AsyncPipe, obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
if ((<any>obj).subscribe) {
|
||||||
_dispose(): void {
|
return _observableStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidPipeArgumentError(AsyncPipe, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _dispose(): void {
|
||||||
this._strategy.dispose(this._subscription);
|
this._strategy.dispose(this._subscription);
|
||||||
this._latestValue = null;
|
this._latestValue = null;
|
||||||
this._latestReturnedValue = null;
|
this._latestReturnedValue = null;
|
||||||
@ -140,8 +131,7 @@ export class AsyncPipe implements OnDestroy {
|
|||||||
this._obj = null;
|
this._obj = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
private _updateLatestValue(async: any, value: Object) {
|
||||||
_updateLatestValue(async: any, value: Object) {
|
|
||||||
if (async === this._obj) {
|
if (async === this._obj) {
|
||||||
this._latestValue = value;
|
this._latestValue = value;
|
||||||
this._ref.markForCheck();
|
this._ref.markForCheck();
|
||||||
|
@ -7,10 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
|
import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
|
||||||
|
|
||||||
import {StringMapWrapper} from '../facade/collection';
|
|
||||||
import {DateFormatter} from '../facade/intl';
|
import {DateFormatter} from '../facade/intl';
|
||||||
import {DateWrapper, NumberWrapper, isBlank, isDate, isString} from '../facade/lang';
|
import {NumberWrapper, isBlank, isDate} from '../facade/lang';
|
||||||
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
|
|
||||||
@ -83,7 +81,7 @@ import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
|||||||
@Pipe({name: 'date', pure: true})
|
@Pipe({name: 'date', pure: true})
|
||||||
export class DatePipe implements PipeTransform {
|
export class DatePipe implements PipeTransform {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
static _ALIASES: {[key: string]: String} = {
|
static _ALIASES: {[key: string]: string} = {
|
||||||
'medium': 'yMMMdjms',
|
'medium': 'yMMMdjms',
|
||||||
'short': 'yMdjm',
|
'short': 'yMdjm',
|
||||||
'fullDate': 'yMMMMEEEEd',
|
'fullDate': 'yMMMMEEEEd',
|
||||||
@ -104,23 +102,15 @@ export class DatePipe implements PipeTransform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (NumberWrapper.isNumeric(value)) {
|
if (NumberWrapper.isNumeric(value)) {
|
||||||
value = DateWrapper.fromMillis(parseFloat(value));
|
value = parseFloat(value);
|
||||||
} else if (isString(value)) {
|
|
||||||
value = DateWrapper.fromISOString(value);
|
|
||||||
}
|
}
|
||||||
if (StringMapWrapper.contains(DatePipe._ALIASES, pattern)) {
|
|
||||||
pattern = <string>StringMapWrapper.get(DatePipe._ALIASES, pattern);
|
return DateFormatter.format(
|
||||||
}
|
new Date(value), this._locale, DatePipe._ALIASES[pattern] || pattern);
|
||||||
return DateFormatter.format(value, this._locale, pattern);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private supports(obj: any): boolean {
|
private supports(obj: any): boolean {
|
||||||
if (isDate(obj) || NumberWrapper.isNumeric(obj)) {
|
return isDate(obj) || NumberWrapper.isNumeric(obj) ||
|
||||||
return true;
|
(typeof obj === 'string' && isDate(new Date(obj)));
|
||||||
}
|
|
||||||
if (isString(obj) && isDate(DateWrapper.fromISOString(obj))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Pipe, PipeTransform} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {StringWrapper, isBlank, isStringMap} from '../facade/lang';
|
import {isBlank, isStringMap} from '../facade/lang';
|
||||||
import {NgLocalization, getPluralCategory} from '../localization';
|
import {NgLocalization, getPluralCategory} from '../localization';
|
||||||
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
@ -43,6 +43,6 @@ export class I18nPluralPipe implements PipeTransform {
|
|||||||
|
|
||||||
const key = getPluralCategory(value, Object.keys(pluralMap), this._localization);
|
const key = getPluralCategory(value, Object.keys(pluralMap), this._localization);
|
||||||
|
|
||||||
return StringWrapper.replaceAll(pluralMap[key], _INTERPOLATION_REGEXP, value.toString());
|
return pluralMap[key].replace(_INTERPOLATION_REGEXP, value.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Pipe, PipeTransform} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {isBlank, isString} from '../facade/lang';
|
import {isBlank} from '../facade/lang';
|
||||||
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
|||||||
export class LowerCasePipe implements PipeTransform {
|
export class LowerCasePipe implements PipeTransform {
|
||||||
transform(value: string): string {
|
transform(value: string): string {
|
||||||
if (isBlank(value)) return value;
|
if (isBlank(value)) return value;
|
||||||
if (!isString(value)) {
|
if (typeof value !== 'string') {
|
||||||
throw new InvalidPipeArgumentError(LowerCasePipe, value);
|
throw new InvalidPipeArgumentError(LowerCasePipe, value);
|
||||||
}
|
}
|
||||||
return value.toLowerCase();
|
return value.toLowerCase();
|
||||||
|
@ -9,21 +9,23 @@
|
|||||||
import {Inject, LOCALE_ID, Pipe, PipeTransform, Type} from '@angular/core';
|
import {Inject, LOCALE_ID, Pipe, PipeTransform, Type} from '@angular/core';
|
||||||
|
|
||||||
import {NumberFormatStyle, NumberFormatter} from '../facade/intl';
|
import {NumberFormatStyle, NumberFormatter} from '../facade/intl';
|
||||||
import {NumberWrapper, isBlank, isNumber, isPresent, isString} from '../facade/lang';
|
import {NumberWrapper, isBlank, isPresent} from '../facade/lang';
|
||||||
|
|
||||||
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
const _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(\-(\d+))?)?$/;
|
const _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
|
||||||
|
|
||||||
function formatNumber(
|
function formatNumber(
|
||||||
pipe: Type<any>, locale: string, value: number | string, style: NumberFormatStyle,
|
pipe: Type<any>, locale: string, value: number | string, style: NumberFormatStyle,
|
||||||
digits: string, currency: string = null, currencyAsSymbol: boolean = false): string {
|
digits: string, currency: string = null, currencyAsSymbol: boolean = false): string {
|
||||||
if (isBlank(value)) return null;
|
if (isBlank(value)) return null;
|
||||||
|
|
||||||
// Convert strings to numbers
|
// Convert strings to numbers
|
||||||
value = isString(value) && NumberWrapper.isNumeric(value) ? +value : value;
|
value = typeof value === 'string' && NumberWrapper.isNumeric(value) ? +value : value;
|
||||||
if (!isNumber(value)) {
|
if (typeof value !== 'number') {
|
||||||
throw new InvalidPipeArgumentError(pipe, value);
|
throw new InvalidPipeArgumentError(pipe, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
let minInt: number;
|
let minInt: number;
|
||||||
let minFraction: number;
|
let minFraction: number;
|
||||||
let maxFraction: number;
|
let maxFraction: number;
|
||||||
@ -34,8 +36,8 @@ function formatNumber(
|
|||||||
maxFraction = 3;
|
maxFraction = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPresent(digits)) {
|
if (digits) {
|
||||||
var parts = digits.match(_NUMBER_FORMAT_REGEXP);
|
let parts = digits.match(_NUMBER_FORMAT_REGEXP);
|
||||||
if (parts === null) {
|
if (parts === null) {
|
||||||
throw new Error(`${digits} is not a valid digit info for number pipes`);
|
throw new Error(`${digits} is not a valid digit info for number pipes`);
|
||||||
}
|
}
|
||||||
@ -49,12 +51,13 @@ function formatNumber(
|
|||||||
maxFraction = NumberWrapper.parseIntAutoRadix(parts[5]);
|
maxFraction = NumberWrapper.parseIntAutoRadix(parts[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NumberFormatter.format(value as number, locale, style, {
|
return NumberFormatter.format(value as number, locale, style, {
|
||||||
minimumIntegerDigits: minInt,
|
minimumIntegerDigits: minInt,
|
||||||
minimumFractionDigits: minFraction,
|
minimumFractionDigits: minFraction,
|
||||||
maximumFractionDigits: maxFraction,
|
maximumFractionDigits: maxFraction,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
currencyAsSymbol: currencyAsSymbol
|
currencyAsSymbol: currencyAsSymbol,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Pipe, PipeTransform} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {ListWrapper} from '../facade/collection';
|
import {isBlank} from '../facade/lang';
|
||||||
import {StringWrapper, isArray, isBlank, isString} from '../facade/lang';
|
|
||||||
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,16 +57,15 @@ import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
|||||||
|
|
||||||
@Pipe({name: 'slice', pure: false})
|
@Pipe({name: 'slice', pure: false})
|
||||||
export class SlicePipe implements PipeTransform {
|
export class SlicePipe implements PipeTransform {
|
||||||
transform(value: any, start: number, end: number = null): any {
|
transform(value: any, start: number, end?: number): any {
|
||||||
if (isBlank(value)) return value;
|
if (isBlank(value)) return value;
|
||||||
|
|
||||||
if (!this.supports(value)) {
|
if (!this.supports(value)) {
|
||||||
throw new InvalidPipeArgumentError(SlicePipe, value);
|
throw new InvalidPipeArgumentError(SlicePipe, value);
|
||||||
}
|
}
|
||||||
if (isString(value)) {
|
|
||||||
return StringWrapper.slice(value, start, end);
|
return value.slice(start, end);
|
||||||
}
|
|
||||||
return ListWrapper.slice(value, start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private supports(obj: any): boolean { return isString(obj) || isArray(obj); }
|
private supports(obj: any): boolean { return typeof obj === 'string' || Array.isArray(obj); }
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Pipe, PipeTransform} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {isBlank, isString} from '../facade/lang';
|
import {isBlank} from '../facade/lang';
|
||||||
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,7 +28,7 @@ import {InvalidPipeArgumentError} from './invalid_pipe_argument_error';
|
|||||||
export class UpperCasePipe implements PipeTransform {
|
export class UpperCasePipe implements PipeTransform {
|
||||||
transform(value: string): string {
|
transform(value: string): string {
|
||||||
if (isBlank(value)) return value;
|
if (isBlank(value)) return value;
|
||||||
if (!isString(value)) {
|
if (typeof value !== 'string') {
|
||||||
throw new InvalidPipeArgumentError(UpperCasePipe, value);
|
throw new InvalidPipeArgumentError(UpperCasePipe, value);
|
||||||
}
|
}
|
||||||
return value.toUpperCase();
|
return value.toUpperCase();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user