1- import { List , ListWrapper } from 'angular2/src/facade/collection' ;
1+ import { ListWrapper , isListLikeIterable , StringMapWrapper } from 'angular2/src/facade/collection' ;
22import { isBlank , isPresent , BaseException , CONST } from 'angular2/src/facade/lang' ;
33import { Pipe , PipeFactory } from './pipe' ;
4- import { Injectable } from 'angular2/src/di/decorators ' ;
4+ import { Injectable , UnboundedMetadata , OptionalMetadata } from 'angular2/di ' ;
55import { ChangeDetectorRef } from '../change_detector_ref' ;
6+ import { Binding } from 'angular2/di' ;
67
78@Injectable ( )
89@CONST ( )
910export class Pipes {
10- constructor ( public config ) { }
11+ /**
12+ * Map of {@link Pipe} names to {@link PipeFactory} lists used to configure the
13+ * {@link Pipes} registry.
14+ *
15+ * #Example
16+ *
17+ * ```
18+ * var pipesConfig = {
19+ * 'json': [jsonPipeFactory]
20+ * }
21+ * @Component ({
22+ * viewInjector: [
23+ * bind(Pipes).toValue(new Pipes(pipesConfig))
24+ * ]
25+ * })
26+ * ```
27+ */
28+ config : StringMap < string , PipeFactory [ ] > ;
29+ constructor ( config : StringMap < string , PipeFactory [ ] > ) { this . config = config ; }
1130
1231 get ( type : string , obj , cdRef ?: ChangeDetectorRef , existingPipe ?: Pipe ) : Pipe {
1332 if ( isPresent ( existingPipe ) && existingPipe . supports ( obj ) ) return existingPipe ;
@@ -20,6 +39,65 @@ export class Pipes {
2039 return factory . create ( cdRef ) ;
2140 }
2241
42+ /**
43+ * Takes a {@link Pipes} config object and returns a binding used to append the
44+ * provided config to an inherited {@link Pipes} instance and return a new
45+ * {@link Pipes} instance.
46+ *
47+ * If the provided config contains a key that is not yet present in the
48+ * inherited {@link Pipes}' config, a new {@link PipeFactory} list will be created
49+ * for that key. Otherwise, the provided config will be merged with the inherited
50+ * {@link Pipes} instance by appending pipes to their respective keys, without mutating
51+ * the inherited {@link Pipes}.
52+ *
53+ * The following example shows how to append a new {@link PipeFactory} to the
54+ * existing list of `async` factories, which will only be applied to the injector
55+ * for this component and its children. This step is all that's required to make a new
56+ * pipe available to this component's template.
57+ *
58+ * # Example
59+ *
60+ * ```
61+ * @Component ({
62+ * viewInjector: [
63+ * Pipes.append({
64+ * async: [newAsyncPipe]
65+ * })
66+ * ]
67+ * })
68+ * ```
69+ */
70+ static append ( config ) : Binding {
71+ return new Binding ( Pipes , {
72+ toFactory : ( pipes : Pipes ) => {
73+ if ( ! isPresent ( pipes ) ) {
74+ // Typically would occur when calling Pipe.append inside of dependencies passed to
75+ // bootstrap(), which would override default pipes instead of append.
76+ throw new BaseException ( 'Cannot append to Pipes without a parent injector' ) ;
77+ }
78+ var mergedConfig : StringMap < string , PipeFactory [ ] > = < StringMap < string , PipeFactory [ ] > > { } ;
79+
80+ // Manual deep copy of existing Pipes config,
81+ // so that lists of PipeFactories don't get mutated.
82+ StringMapWrapper . forEach ( pipes . config , ( v : PipeFactory [ ] , k : string ) => {
83+ var localPipeList : PipeFactory [ ] = mergedConfig [ k ] = [ ] ;
84+ v . forEach ( ( p : PipeFactory ) => { localPipeList . push ( p ) ; } ) ;
85+ } ) ;
86+
87+ StringMapWrapper . forEach ( config , ( v : PipeFactory [ ] , k : string ) => {
88+ if ( isListLikeIterable ( mergedConfig [ k ] ) ) {
89+ mergedConfig [ k ] = ListWrapper . concat ( mergedConfig [ k ] , config [ k ] ) ;
90+ } else {
91+ mergedConfig [ k ] = config [ k ] ;
92+ }
93+ } ) ;
94+ return new Pipes ( mergedConfig ) ;
95+ } ,
96+ // Dependency technically isn't optional, but we can provide a better error message this way.
97+ deps : [ [ Pipes , new UnboundedMetadata ( ) , new OptionalMetadata ( ) ] ]
98+ } )
99+ }
100+
23101 private _getListOfFactories ( type : string , obj : any ) : PipeFactory [ ] {
24102 var listOfFactories = this . config [ type ] ;
25103 if ( isBlank ( listOfFactories ) ) {
0 commit comments