feat(di): added hostInjector and viewInjector to the Directive annotation

This commit is contained in:
vsavkin
2015-05-16 11:01:02 -07:00
parent 7b511462af
commit b066b8d15a
14 changed files with 877 additions and 439 deletions
@@ -660,6 +660,37 @@ export class Directive extends Injectable {
//TODO(vsavkin): This would better fall under the Macro directive concept.
compileChildren: boolean;
/**
* Defines the set of injectable objects that are visible to a Directive and its light dom children.
*
* ## Simple Example
*
* Here is an example of a class that can be injected:
*
* ```
* class Greeter {
* greet(name:string) {
* return 'Hello ' + name + '!';
* }
* }
*
* @Directive({
* selector: 'greet',
* hostInjector: [
* Greeter
* ]
* })
* class HelloWorld {
* greeter:Greeter;
*
* constructor(greeter:Greeter) {
* this.greeter = greeter;
* }
* }
* ```
*/
hostInjector:List;
@CONST()
constructor({
selector,
@@ -670,6 +701,7 @@ export class Directive extends Injectable {
hostAttributes,
hostActions,
lifecycle,
hostInjector,
compileChildren = true,
}:{
selector:string,
@@ -680,6 +712,7 @@ export class Directive extends Injectable {
hostAttributes: any,
hostActions: any,
lifecycle:List,
hostInjector:List,
compileChildren:boolean
}={})
{
@@ -693,6 +726,7 @@ export class Directive extends Injectable {
this.hostActions = hostActions;
this.lifecycle = lifecycle;
this.compileChildren = compileChildren;
this.hostInjector = hostInjector;
}
/**
@@ -845,6 +879,48 @@ export class Component extends Directive {
*/
appInjector:List;
/**
* Defines the set of injectable objects that are visible to its view dom children.
*
* ## Simple Example
*
* Here is an example of a class that can be injected:
*
* ```
* class Greeter {
* greet(name:string) {
* return 'Hello ' + name + '!';
* }
* }
*
* @Directive({
* selector: 'needs-greeter'
* })
* class NeedsGreeter {
* greeter:Greeter;
*
* constructor(greeter:Greeter) {
* this.greeter = greeter;
* }
* }
*
* @Component({
* selector: 'greet',
* viewInjector: [
* Greeter
* ]
* })
* @View({
* template: `<needs-greeter></needs-greeter>`,
* directives: [NeedsGreeter]
* })
* class HelloWorld {
* }
*
* ```
*/
viewInjector:List;
@CONST()
constructor({
selector,
@@ -856,6 +932,8 @@ export class Component extends Directive {
hostActions,
appInjector,
lifecycle,
hostInjector,
viewInjector,
changeDetection = DEFAULT,
compileChildren = true
}:{
@@ -868,6 +946,8 @@ export class Component extends Directive {
hostActions:any,
appInjector:List,
lifecycle:List,
hostInjector:List,
viewInjector:List,
changeDetection:string,
compileChildren:boolean
}={})
@@ -880,12 +960,14 @@ export class Component extends Directive {
hostProperties: hostProperties,
hostAttributes: hostAttributes,
hostActions: hostActions,
hostInjector: hostInjector,
lifecycle: lifecycle,
compileChildren: compileChildren
});
this.changeDetection = changeDetection;
this.appInjector = appInjector;
this.viewInjector = viewInjector;
}
}
+106 -5
View File
@@ -1,6 +1,66 @@
import {CONST} from 'angular2/src/facade/lang';
import {DependencyAnnotation} from 'angular2/src/di/annotations_impl';
export class Visibility extends DependencyAnnotation {
depth: number;
crossComponentBoundaries: boolean;
@CONST()
constructor(depth:number, crossComponentBoundaries:boolean) {
super();
this.depth = depth;
this.crossComponentBoundaries = crossComponentBoundaries;
}
shouldIncludeSelf():boolean {
return this.depth === 0;
}
}
/**
* Specifies that an injector should retrieve a dependency from its element.
*
* ## Example
*
* Here is a simple directive that retrieves a dependency from its element.
*
* ```
* @Directive({
* selector: '[dependency]',
* properties: {
* 'id':'dependency'
* }
* })
* class Dependency {
* id:string;
* }
*
*
* @Directive({
* selector: '[my-directive]'
* })
* class Dependency {
* constructor(@Self() dependency:Dependency) {
* expect(dependency.id).toEqual(1);
* };
* }
* ```
*
* We use this with the following HTML template:
*
* ```
*<div dependency="1" my-directive></div>
* ```
*
* @exportedAs angular2/annotations
*/
export class Self extends Visibility {
@CONST()
constructor() {
super(0, false);
}
}
/**
* Specifies that an injector should retrieve a dependency from the direct parent.
*
@@ -42,15 +102,15 @@ import {DependencyAnnotation} from 'angular2/src/di/annotations_impl';
*
* @exportedAs angular2/annotations
*/
export class Parent extends DependencyAnnotation {
export class Parent extends Visibility {
@CONST()
constructor() {
super();
super(1, false);
}
}
/**
* Specifies that an injector should retrieve a dependency from any ancestor element.
* Specifies that an injector should retrieve a dependency from any ancestor element within the same shadow boundary.
*
* An ancestor is any element between the parent element and shadow root.
*
@@ -103,9 +163,50 @@ export class Parent extends DependencyAnnotation {
*
* @exportedAs angular2/annotations
*/
export class Ancestor extends DependencyAnnotation {
export class Ancestor extends Visibility {
@CONST()
constructor() {
super();
super(999999, false);
}
}
/**
* Specifies that an injector should retrieve a dependency from any ancestor element.
*
* An ancestor is any element between the parent element and shadow root.
*
*
* ## Example
*
* Here is a simple directive that retrieves a dependency from an ancestor element.
*
* ```
* @Directive({
* selector: '[dependency]',
* properties: {
* 'id':'dependency'
* }
* })
* class Dependency {
* id:string;
* }
*
*
* @Directive({
* selector: '[my-directive]'
* })
* class Dependency {
* constructor(@Unbounded() dependency:Dependency) {
* expect(dependency.id).toEqual(2);
* };
* }
* ```
*
* @exportedAs angular2/annotations
*/
export class Unbounded extends Visibility {
@CONST()
constructor() {
super(999999, true);
}
}