1
- import { List , ListWrapper } from 'angular2/src/facade/collection' ;
1
+ import { ListWrapper , isListLikeIterable , StringMapWrapper } from 'angular2/src/facade/collection' ;
2
2
import { isBlank , isPresent , BaseException , CONST } from 'angular2/src/facade/lang' ;
3
3
import { Pipe , PipeFactory } from './pipe' ;
4
- import { Injectable } from 'angular2/src/di/decorators ' ;
4
+ import { Injectable , UnboundedMetadata , OptionalMetadata } from 'angular2/di ' ;
5
5
import { ChangeDetectorRef } from '../change_detector_ref' ;
6
+ import { Binding } from 'angular2/di' ;
6
7
7
8
@Injectable ( )
8
9
@CONST ( )
9
10
export 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 ; }
11
30
12
31
get ( type : string , obj , cdRef ?: ChangeDetectorRef , existingPipe ?: Pipe ) : Pipe {
13
32
if ( isPresent ( existingPipe ) && existingPipe . supports ( obj ) ) return existingPipe ;
@@ -20,6 +39,65 @@ export class Pipes {
20
39
return factory . create ( cdRef ) ;
21
40
}
22
41
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
+
23
101
private _getListOfFactories ( type : string , obj : any ) : PipeFactory [ ] {
24
102
var listOfFactories = this . config [ type ] ;
25
103
if ( isBlank ( listOfFactories ) ) {
0 commit comments