Skip to content

Commit b066b8d

Browse files
committed
feat(di): added hostInjector and viewInjector to the Directive annotation
1 parent 7b51146 commit b066b8d

14 files changed

Lines changed: 875 additions & 437 deletions

modules/angular2/di.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
export * from './src/di/annotations';
99
export * from './src/di/decorators';
1010
export * from './src/di/forward_ref';
11-
export {Injector} from './src/di/injector';
11+
export {resolveBindings, Injector} from './src/di/injector';
1212
export {Binding, ResolvedBinding, Dependency, bind} from './src/di/binding';
1313
export {Key, KeyRegistry, TypeLiteral} from './src/di/key';
1414
export {

modules/angular2/src/core/annotations_impl/annotations.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,37 @@ export class Directive extends Injectable {
660660
//TODO(vsavkin): This would better fall under the Macro directive concept.
661661
compileChildren: boolean;
662662

663+
/**
664+
* Defines the set of injectable objects that are visible to a Directive and its light dom children.
665+
*
666+
* ## Simple Example
667+
*
668+
* Here is an example of a class that can be injected:
669+
*
670+
* ```
671+
* class Greeter {
672+
* greet(name:string) {
673+
* return 'Hello ' + name + '!';
674+
* }
675+
* }
676+
*
677+
* @Directive({
678+
* selector: 'greet',
679+
* hostInjector: [
680+
* Greeter
681+
* ]
682+
* })
683+
* class HelloWorld {
684+
* greeter:Greeter;
685+
*
686+
* constructor(greeter:Greeter) {
687+
* this.greeter = greeter;
688+
* }
689+
* }
690+
* ```
691+
*/
692+
hostInjector:List;
693+
663694
@CONST()
664695
constructor({
665696
selector,
@@ -670,6 +701,7 @@ export class Directive extends Injectable {
670701
hostAttributes,
671702
hostActions,
672703
lifecycle,
704+
hostInjector,
673705
compileChildren = true,
674706
}:{
675707
selector:string,
@@ -680,6 +712,7 @@ export class Directive extends Injectable {
680712
hostAttributes: any,
681713
hostActions: any,
682714
lifecycle:List,
715+
hostInjector:List,
683716
compileChildren:boolean
684717
}={})
685718
{
@@ -693,6 +726,7 @@ export class Directive extends Injectable {
693726
this.hostActions = hostActions;
694727
this.lifecycle = lifecycle;
695728
this.compileChildren = compileChildren;
729+
this.hostInjector = hostInjector;
696730
}
697731

698732
/**
@@ -845,6 +879,48 @@ export class Component extends Directive {
845879
*/
846880
appInjector:List;
847881

882+
/**
883+
* Defines the set of injectable objects that are visible to its view dom children.
884+
*
885+
* ## Simple Example
886+
*
887+
* Here is an example of a class that can be injected:
888+
*
889+
* ```
890+
* class Greeter {
891+
* greet(name:string) {
892+
* return 'Hello ' + name + '!';
893+
* }
894+
* }
895+
*
896+
* @Directive({
897+
* selector: 'needs-greeter'
898+
* })
899+
* class NeedsGreeter {
900+
* greeter:Greeter;
901+
*
902+
* constructor(greeter:Greeter) {
903+
* this.greeter = greeter;
904+
* }
905+
* }
906+
*
907+
* @Component({
908+
* selector: 'greet',
909+
* viewInjector: [
910+
* Greeter
911+
* ]
912+
* })
913+
* @View({
914+
* template: `<needs-greeter></needs-greeter>`,
915+
* directives: [NeedsGreeter]
916+
* })
917+
* class HelloWorld {
918+
* }
919+
*
920+
* ```
921+
*/
922+
viewInjector:List;
923+
848924
@CONST()
849925
constructor({
850926
selector,
@@ -856,6 +932,8 @@ export class Component extends Directive {
856932
hostActions,
857933
appInjector,
858934
lifecycle,
935+
hostInjector,
936+
viewInjector,
859937
changeDetection = DEFAULT,
860938
compileChildren = true
861939
}:{
@@ -868,6 +946,8 @@ export class Component extends Directive {
868946
hostActions:any,
869947
appInjector:List,
870948
lifecycle:List,
949+
hostInjector:List,
950+
viewInjector:List,
871951
changeDetection:string,
872952
compileChildren:boolean
873953
}={})
@@ -880,12 +960,14 @@ export class Component extends Directive {
880960
hostProperties: hostProperties,
881961
hostAttributes: hostAttributes,
882962
hostActions: hostActions,
963+
hostInjector: hostInjector,
883964
lifecycle: lifecycle,
884965
compileChildren: compileChildren
885966
});
886967

887968
this.changeDetection = changeDetection;
888969
this.appInjector = appInjector;
970+
this.viewInjector = viewInjector;
889971
}
890972
}
891973

modules/angular2/src/core/annotations_impl/visibility.js

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,66 @@
11
import {CONST} from 'angular2/src/facade/lang';
22
import {DependencyAnnotation} from 'angular2/src/di/annotations_impl';
33

4+
export class Visibility extends DependencyAnnotation {
5+
depth: number;
6+
crossComponentBoundaries: boolean;
7+
8+
@CONST()
9+
constructor(depth:number, crossComponentBoundaries:boolean) {
10+
super();
11+
this.depth = depth;
12+
this.crossComponentBoundaries = crossComponentBoundaries;
13+
}
14+
15+
shouldIncludeSelf():boolean {
16+
return this.depth === 0;
17+
}
18+
}
19+
20+
/**
21+
* Specifies that an injector should retrieve a dependency from its element.
22+
*
23+
* ## Example
24+
*
25+
* Here is a simple directive that retrieves a dependency from its element.
26+
*
27+
* ```
28+
* @Directive({
29+
* selector: '[dependency]',
30+
* properties: {
31+
* 'id':'dependency'
32+
* }
33+
* })
34+
* class Dependency {
35+
* id:string;
36+
* }
37+
*
38+
*
39+
* @Directive({
40+
* selector: '[my-directive]'
41+
* })
42+
* class Dependency {
43+
* constructor(@Self() dependency:Dependency) {
44+
* expect(dependency.id).toEqual(1);
45+
* };
46+
* }
47+
* ```
48+
*
49+
* We use this with the following HTML template:
50+
*
51+
* ```
52+
*<div dependency="1" my-directive></div>
53+
* ```
54+
*
55+
* @exportedAs angular2/annotations
56+
*/
57+
export class Self extends Visibility {
58+
@CONST()
59+
constructor() {
60+
super(0, false);
61+
}
62+
}
63+
464
/**
565
* Specifies that an injector should retrieve a dependency from the direct parent.
666
*
@@ -42,15 +102,15 @@ import {DependencyAnnotation} from 'angular2/src/di/annotations_impl';
42102
*
43103
* @exportedAs angular2/annotations
44104
*/
45-
export class Parent extends DependencyAnnotation {
105+
export class Parent extends Visibility {
46106
@CONST()
47107
constructor() {
48-
super();
108+
super(1, false);
49109
}
50110
}
51111

52112
/**
53-
* Specifies that an injector should retrieve a dependency from any ancestor element.
113+
* Specifies that an injector should retrieve a dependency from any ancestor element within the same shadow boundary.
54114
*
55115
* An ancestor is any element between the parent element and shadow root.
56116
*
@@ -103,9 +163,50 @@ export class Parent extends DependencyAnnotation {
103163
*
104164
* @exportedAs angular2/annotations
105165
*/
106-
export class Ancestor extends DependencyAnnotation {
166+
export class Ancestor extends Visibility {
107167
@CONST()
108168
constructor() {
109-
super();
169+
super(999999, false);
170+
}
171+
}
172+
173+
/**
174+
* Specifies that an injector should retrieve a dependency from any ancestor element.
175+
*
176+
* An ancestor is any element between the parent element and shadow root.
177+
*
178+
*
179+
* ## Example
180+
*
181+
* Here is a simple directive that retrieves a dependency from an ancestor element.
182+
*
183+
* ```
184+
* @Directive({
185+
* selector: '[dependency]',
186+
* properties: {
187+
* 'id':'dependency'
188+
* }
189+
* })
190+
* class Dependency {
191+
* id:string;
192+
* }
193+
*
194+
*
195+
* @Directive({
196+
* selector: '[my-directive]'
197+
* })
198+
* class Dependency {
199+
* constructor(@Unbounded() dependency:Dependency) {
200+
* expect(dependency.id).toEqual(2);
201+
* };
202+
* }
203+
* ```
204+
*
205+
* @exportedAs angular2/annotations
206+
*/
207+
export class Unbounded extends Visibility {
208+
@CONST()
209+
constructor() {
210+
super(999999, true);
110211
}
111212
}

0 commit comments

Comments
 (0)