Skip to content

Commit 600d53c

Browse files
piloopinvsavkin
authored andcommitted
feat(pipes): support arguments in transform function
1 parent f0e962c commit 600d53c

19 files changed

+74
-41
lines changed

Diff for: modules/angular2/src/change_detection/change_detection_jit_generator.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ export class ChangeDetectorJITGenerator {
240240

241241
_genPipeCheck(r: ProtoRecord): string {
242242
var context = this._localNames[r.contextIndex];
243+
var argString = r.args.map((arg) => this._localNames[arg]).join(", ");
244+
243245
var oldValue = this._fieldNames[r.selfIndex];
244246
var newValue = this._localNames[r.selfIndex];
245247
var change = this._changeNames[r.selfIndex];
@@ -259,7 +261,7 @@ export class ChangeDetectorJITGenerator {
259261
${pipe} = ${PIPE_REGISTRY_ACCESSOR}.get('${pipeType}', ${context}, ${cdRef});
260262
}
261263
262-
${newValue} = ${pipe}.transform(${context});
264+
${newValue} = ${pipe}.transform(${context}, [${argString}]);
263265
if (${oldValue} !== ${newValue}) {
264266
${newValue} = ${UTIL}.unwrapValue(${newValue});
265267
${change} = true;

Diff for: modules/angular2/src/change_detection/dynamic_change_detector.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,11 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
233233

234234
_pipeCheck(proto: ProtoRecord, throwOnChange: boolean) {
235235
var context = this._readContext(proto);
236+
var args = this._readArgs(proto);
237+
236238
var pipe = this._pipeFor(proto, context);
237239
var prevValue = this._readSelf(proto);
238-
239-
var currValue = pipe.transform(context);
240+
var currValue = pipe.transform(context, args);
240241

241242
if (!isSame(prevValue, currValue)) {
242243
currValue = ChangeDetectionUtil.unwrapValue(currValue);

Diff for: modules/angular2/src/change_detection/pipes/iterable_changes.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ import {
1616
} from 'angular2/src/facade/lang';
1717

1818
import {WrappedValue, Pipe, BasePipe, PipeFactory} from './pipe';
19+
import {ChangeDetectorRef} from '../change_detector_ref';
1920

2021
@CONST()
2122
export class IterableChangesFactory implements PipeFactory {
2223
supports(obj): boolean { return IterableChanges.supportsObj(obj); }
2324

24-
create(cdRef): Pipe { return new IterableChanges(); }
25+
create(cdRef: ChangeDetectorRef): Pipe { return new IterableChanges(); }
2526
}
2627

2728
/**
@@ -89,7 +90,7 @@ export class IterableChanges extends BasePipe {
8990
}
9091
}
9192

92-
transform(collection): any {
93+
transform(collection, args: List<any> = null): any {
9394
if (this.check(collection)) {
9495
return WrappedValue.wrap(this);
9596
} else {

Diff for: modules/angular2/src/change_detection/pipes/json_pipe.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {isBlank, isPresent, Json, CONST} from 'angular2/src/facade/lang';
22
import {Pipe, BasePipe, PipeFactory} from './pipe';
3+
import {ChangeDetectorRef} from '../change_detector_ref';
34

45
/**
56
* Implements json transforms to any object.
@@ -27,8 +28,8 @@ import {Pipe, BasePipe, PipeFactory} from './pipe';
2728
* @exportedAs angular2/pipes
2829
*/
2930
@CONST()
30-
export class JsonPipe extends BasePipe {
31-
transform(value): string { return Json.stringify(value); }
31+
export class JsonPipe extends BasePipe implements PipeFactory {
32+
transform(value, args: List<any> = null): string { return Json.stringify(value); }
3233

33-
create(cdRef): Pipe { return this }
34+
create(cdRef: ChangeDetectorRef): Pipe { return this }
3435
}

Diff for: modules/angular2/src/change_detection/pipes/keyvalue_changes.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
22
import {stringify, looseIdentical, isJsObject, CONST} from 'angular2/src/facade/lang';
3-
3+
import {ChangeDetectorRef} from '../change_detector_ref';
44
import {WrappedValue, BasePipe, Pipe, PipeFactory} from './pipe';
55

66
/**
@@ -10,7 +10,7 @@ import {WrappedValue, BasePipe, Pipe, PipeFactory} from './pipe';
1010
export class KeyValueChangesFactory implements PipeFactory {
1111
supports(obj): boolean { return KeyValueChanges.supportsObj(obj); }
1212

13-
create(cdRef): Pipe { return new KeyValueChanges(); }
13+
create(cdRef: ChangeDetectorRef): Pipe { return new KeyValueChanges(); }
1414
}
1515

1616
/**
@@ -31,7 +31,7 @@ export class KeyValueChanges extends BasePipe {
3131

3232
supports(obj): boolean { return KeyValueChanges.supportsObj(obj); }
3333

34-
transform(map): any {
34+
transform(map, args: List<any> = null): any {
3535
if (this.check(map)) {
3636
return WrappedValue.wrap(this);
3737
} else {

Diff for: modules/angular2/src/change_detection/pipes/lowercase_pipe.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {isString, StringWrapper, CONST} from 'angular2/src/facade/lang';
2-
import {Pipe} from './pipe';
2+
import {Pipe, PipeFactory} from './pipe';
3+
import {ChangeDetectorRef} from '../change_detector_ref';
34

45
/**
56
* Implements lowercase transforms to text.
@@ -30,7 +31,7 @@ export class LowerCasePipe implements Pipe {
3031

3132
onDestroy(): void { this._latestValue = null; }
3233

33-
transform(value: string): string {
34+
transform(value: string, args: List<any> = null): string {
3435
if (this._latestValue !== value) {
3536
this._latestValue = value;
3637
return StringWrapper.toLowerCase(value);
@@ -44,8 +45,8 @@ export class LowerCasePipe implements Pipe {
4445
* @exportedAs angular2/pipes
4546
*/
4647
@CONST()
47-
export class LowerCaseFactory {
48+
export class LowerCaseFactory implements PipeFactory {
4849
supports(str): boolean { return isString(str); }
4950

50-
create(): Pipe { return new LowerCasePipe(); }
51+
create(cdRef: ChangeDetectorRef): Pipe { return new LowerCasePipe(); }
5152
}

Diff for: modules/angular2/src/change_detection/pipes/null_pipe.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {isBlank, CONST} from 'angular2/src/facade/lang';
22
import {Pipe, BasePipe, WrappedValue, PipeFactory} from './pipe';
3+
import {ChangeDetectorRef} from '../change_detector_ref';
34

45
/**
56
* @exportedAs angular2/pipes
@@ -8,7 +9,7 @@ import {Pipe, BasePipe, WrappedValue, PipeFactory} from './pipe';
89
export class NullPipeFactory implements PipeFactory {
910
supports(obj): boolean { return NullPipe.supportsObj(obj); }
1011

11-
create(cdRef): Pipe { return new NullPipe(); }
12+
create(cdRef: ChangeDetectorRef): Pipe { return new NullPipe(); }
1213
}
1314

1415
/**
@@ -21,7 +22,7 @@ export class NullPipe extends BasePipe {
2122

2223
supports(obj): boolean { return NullPipe.supportsObj(obj); }
2324

24-
transform(value): WrappedValue {
25+
transform(value, args: List<any> = null): WrappedValue {
2526
if (!this.called) {
2627
this.called = true;
2728
return WrappedValue.wrap(null);

Diff for: modules/angular2/src/change_detection/pipes/observable_pipe.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class ObservablePipe implements Pipe {
4646
}
4747
}
4848

49-
transform(obs: Observable): any {
49+
transform(obs: Observable, args: List<any> = null): any {
5050
if (isBlank(this._subscription)) {
5151
this._subscribe(obs);
5252
return null;
@@ -94,5 +94,5 @@ export class ObservablePipe implements Pipe {
9494
export class ObservablePipeFactory implements PipeFactory {
9595
supports(obs): boolean { return ObservableWrapper.isObservable(obs); }
9696

97-
create(cdRef): Pipe { return new ObservablePipe(cdRef); }
97+
create(cdRef: ChangeDetectorRef): Pipe { return new ObservablePipe(cdRef); }
9898
}

Diff for: modules/angular2/src/change_detection/pipes/pipe.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {ABSTRACT, BaseException, CONST} from 'angular2/src/facade/lang';
2+
import {ChangeDetectorRef} from '../change_detector_ref';
23

34
/**
45
* Indicates that the result of a {@link Pipe} transformation has changed even though the reference
@@ -43,7 +44,7 @@ var _wrappedIndex = 0;
4344
*
4445
* onDestroy() {}
4546
*
46-
* transform(value) {
47+
* transform(value, args = []) {
4748
* return `${value}${value}`;
4849
* }
4950
* }
@@ -54,7 +55,7 @@ var _wrappedIndex = 0;
5455
export interface Pipe {
5556
supports(obj): boolean;
5657
onDestroy(): void;
57-
transform(value: any): any;
58+
transform(value: any, args: List<any>): any;
5859
}
5960

6061
/**
@@ -74,12 +75,12 @@ export interface Pipe {
7475
export class BasePipe implements Pipe {
7576
supports(obj): boolean { return true; }
7677
onDestroy(): void {}
77-
transform(value: any): any { return _abstract(); }
78+
transform(value: any, args: List<any>): any { return _abstract(); }
7879
}
7980

8081
export interface PipeFactory {
8182
supports(obs): boolean;
82-
create(cdRef): Pipe;
83+
create(cdRef: ChangeDetectorRef): Pipe;
8384
}
8485

8586
function _abstract() {

Diff for: modules/angular2/src/change_detection/pipes/promise_pipe.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
22
import {isBlank, isPresent, isPromise, CONST} from 'angular2/src/facade/lang';
3-
import {Pipe, WrappedValue} from './pipe';
3+
import {Pipe, PipeFactory, WrappedValue} from './pipe';
44
import {ChangeDetectorRef} from '../change_detector_ref';
55

66
/**
@@ -45,7 +45,7 @@ export class PromisePipe implements Pipe {
4545
}
4646
}
4747

48-
transform(promise: Promise<any>): any {
48+
transform(promise: Promise<any>, args: List<any> = null): any {
4949
if (isBlank(this._sourcePromise)) {
5050
this._sourcePromise = promise;
5151
promise.then((val) => {
@@ -81,8 +81,8 @@ export class PromisePipe implements Pipe {
8181
* @exportedAs angular2/pipes
8282
*/
8383
@CONST()
84-
export class PromisePipeFactory {
84+
export class PromisePipeFactory implements PipeFactory {
8585
supports(promise): boolean { return isPromise(promise); }
8686

87-
create(cdRef): Pipe { return new PromisePipe(cdRef); }
87+
create(cdRef: ChangeDetectorRef): Pipe { return new PromisePipe(cdRef); }
8888
}

Diff for: modules/angular2/src/change_detection/pipes/uppercase_pipe.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {isString, StringWrapper, CONST} from 'angular2/src/facade/lang';
2-
import {Pipe} from './pipe';
2+
import {Pipe, PipeFactory} from './pipe';
3+
import {ChangeDetectorRef} from '../change_detector_ref';
34

45
/**
56
* Implements uppercase transforms to text.
@@ -30,7 +31,7 @@ export class UpperCasePipe implements Pipe {
3031

3132
onDestroy(): void { this._latestValue = null; }
3233

33-
transform(value: string): string {
34+
transform(value: string, args: List<any> = null): string {
3435
if (this._latestValue !== value) {
3536
this._latestValue = value;
3637
return StringWrapper.toUpperCase(value);
@@ -44,8 +45,8 @@ export class UpperCasePipe implements Pipe {
4445
* @exportedAs angular2/pipes
4546
*/
4647
@CONST()
47-
export class UpperCaseFactory {
48+
export class UpperCaseFactory implements PipeFactory {
4849
supports(str): boolean { return isString(str); }
4950

50-
create(): Pipe { return new UpperCasePipe(); }
51+
create(cdRef: ChangeDetectorRef): Pipe { return new UpperCasePipe(); }
5152
}

Diff for: modules/angular2/src/change_detection/proto_change_detector.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ class _ConvertAstIntoProtoRecords implements AstVisitor {
181181

182182
visitPipe(ast: BindingPipe): number {
183183
var value = ast.exp.visit(this);
184-
return this._addRecord(RecordType.PIPE, ast.name, ast.name, [], null, value);
184+
var args = this._visitAll(ast.args);
185+
return this._addRecord(RecordType.PIPE, ast.name, ast.name, args, null, value);
185186
}
186187

187188
visitKeyedAccess(ast: KeyedAccess): number {

Diff for: modules/angular2/src/directives/class.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class CSSClass {
2828
}
2929

3030
onCheck(): void {
31-
var diff = this._pipe.transform(this._rawClass);
31+
var diff = this._pipe.transform(this._rawClass, null);
3232
if (isPresent(diff) && isPresent(diff.wrapped)) {
3333
if (diff.wrapped instanceof IterableChanges) {
3434
this._applyArrayChanges(diff.wrapped);

Diff for: modules/angular2/src/directives/ng_for.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class NgFor {
5555
}
5656

5757
onCheck() {
58-
var diff = this._pipe.transform(this._ngForOf);
58+
var diff = this._pipe.transform(this._ngForOf, null);
5959
if (isPresent(diff)) this._applyChanges(diff.wrapped);
6060
}
6161

Diff for: modules/angular2/src/directives/ng_style.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export class NgStyle {
2020
}
2121

2222
onCheck() {
23-
var diff = this._pipe.transform(this._rawStyle);
23+
var diff = this._pipe.transform(this._rawStyle, null);
2424
if (isPresent(diff) && isPresent(diff.wrapped)) {
2525
this._applyChanges(diff.wrapped);
2626
}

Diff for: modules/angular2/src/transform/template_compiler/change_detector_codegen.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ class _CodegenState {
304304

305305
String _genPipeCheck(ProtoRecord r) {
306306
var context = _localNames[r.contextIndex];
307+
var argString = r.args.map((arg) => this._localNames[arg]).join(", ");
308+
307309
var oldValue = _fieldNames[r.selfIndex];
308310
var newValue = _localNames[r.selfIndex];
309311
var change = _changeNames[r.selfIndex];
@@ -322,7 +324,7 @@ class _CodegenState {
322324
$pipe = $_PIPE_REGISTRY_ACCESSOR.get('$pipeType', $context, $cdRef);
323325
}
324326
325-
$newValue = $pipe.transform($context);
327+
$newValue = $pipe.transform($context, [$argString]);
326328
if (!$_IDENTICAL_CHECK_FN($oldValue, $newValue)) {
327329
$newValue = $_UTIL.unwrapValue($newValue);
328330
$change = true;

Diff for: modules/angular2/test/change_detection/change_detector_config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ var _availableDefinitions = [
300300
'{z: 1}',
301301
'{z: a}',
302302
'name | pipe',
303+
"name | pipe:'one':address.city",
303304
'value',
304305
'a',
305306
'address.city',

Diff for: modules/angular2/test/change_detection/change_detector_spec.ts

+24-4
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,15 @@ export function main() {
333333
val.changeDetector.detectChanges();
334334
expect(val.dispatcher.loggedValues).toEqual(['bob state:0']);
335335
});
336+
337+
it('should support arguments in pipes', () => {
338+
var registry = new FakePipeRegistry('pipe', () => new MultiArgPipe());
339+
var address = new Address('two');
340+
var person = new Person('value', address);
341+
var val = _createChangeDetector("name | pipe:'one':address.city", person, registry);
342+
val.changeDetector.detectChanges();
343+
expect(val.dispatcher.loggedValues).toEqual(['value one two default']);
344+
});
336345
});
337346

338347
it('should notify the dispatcher on all changes done', () => {
@@ -861,7 +870,7 @@ class CountingPipe implements Pipe {
861870

862871
supports(newValue) { return true; }
863872

864-
transform(value) { return `${value} state:${this.state ++}`; }
873+
transform(value, args = null) { return `${value} state:${this.state ++}`; }
865874
}
866875

867876
class OncePipe implements Pipe {
@@ -872,7 +881,7 @@ class OncePipe implements Pipe {
872881

873882
onDestroy() { this.destroyCalled = true; }
874883

875-
transform(value) {
884+
transform(value, args = null) {
876885
this.called = true;
877886
return value;
878887
}
@@ -883,15 +892,26 @@ class IdentityPipe implements Pipe {
883892

884893
onDestroy() {}
885894

886-
transform(value) { return value; }
895+
transform(value, args = null) { return value; }
887896
}
888897

889898
class WrappedPipe implements Pipe {
890899
supports(obj): boolean { return true; }
891900

892901
onDestroy() {}
893902

894-
transform(value) { return WrappedValue.wrap(value); }
903+
transform(value, args = null) { return WrappedValue.wrap(value); }
904+
}
905+
906+
class MultiArgPipe implements Pipe {
907+
transform(value, args = null) {
908+
var arg1 = args[0];
909+
var arg2 = args[1];
910+
var arg3 = args.length > 2 ? args[2] : 'default';
911+
return `${value} ${arg1} ${arg2} ${arg3}`;
912+
}
913+
supports(obj): boolean { return true; }
914+
onDestroy(): void {}
895915
}
896916

897917
class FakePipeRegistry extends PipeRegistry {

Diff for: modules/angular2/test/core/compiler/integration_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ class DoublePipe implements Pipe {
14731473

14741474
supports(obj) { return true; }
14751475

1476-
transform(value) { return `${value}${value}`; }
1476+
transform(value, args = null) { return `${value}${value}`; }
14771477
}
14781478

14791479
@Injectable()

0 commit comments

Comments
 (0)