feat(di): removed app injector
BREAKING CHANGE: THe appInjector property has been removed. Instead use viewInjector or hostInjector.
This commit is contained in:
parent
73a939e76c
commit
f0e962c55e
|
@ -36,9 +36,7 @@ export {
|
||||||
PUBLIC_AND_PRIVATE,
|
PUBLIC_AND_PRIVATE,
|
||||||
PUBLIC,
|
PUBLIC,
|
||||||
PRIVATE,
|
PRIVATE,
|
||||||
undefinedValue,
|
undefinedValue
|
||||||
InjectorInlineStrategy,
|
|
||||||
InjectorDynamicStrategy
|
|
||||||
} from './src/di/injector';
|
} from './src/di/injector';
|
||||||
export {Binding, BindingBuilder, ResolvedBinding, Dependency, bind} from './src/di/binding';
|
export {Binding, BindingBuilder, ResolvedBinding, Dependency, bind} from './src/di/binding';
|
||||||
export {Key, KeyRegistry, TypeLiteral} from './src/di/key';
|
export {Key, KeyRegistry, TypeLiteral} from './src/di/key';
|
||||||
|
|
|
@ -216,7 +216,7 @@ To better understand the kinds of injections which are supported in Angular we h
|
||||||
|
|
||||||
### Injecting Services
|
### Injecting Services
|
||||||
|
|
||||||
Service injection is the most straight forward kind of injection which Angular supports. It involves a component configuring the `appInjector` and then letting the directive ask for the configured service.
|
Service injection is the most straight forward kind of injection which Angular supports. It involves a component configuring the `viewInjector` or `hostInjector` and then letting the directive ask for the configured service.
|
||||||
|
|
||||||
This example illustrates how to inject `MyService` into `House` directive.
|
This example illustrates how to inject `MyService` into `House` directive.
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ class MyService {} | Assume a service which needs to be inject
|
||||||
|
|
|
|
||||||
@Component({ | Assume a top level application component which
|
@Component({ | Assume a top level application component which
|
||||||
selector: 'my-app', | configures the services to be injected.
|
selector: 'my-app', | configures the services to be injected.
|
||||||
appInjector: [MyService] |
|
viewInjector: [MyService] |
|
||||||
}) |
|
}) |
|
||||||
@View({ | Assume we have a template that needs to be
|
@View({ | Assume we have a template that needs to be
|
||||||
templateUrl: 'my_app.html', | configured with directives to be injected.
|
templateUrl: 'my_app.html', | configured with directives to be injected.
|
||||||
|
@ -329,8 +329,7 @@ Shadow DOM provides an encapsulation for components, so as a general rule it doe
|
||||||
|
|
||||||
```
|
```
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[kid]',
|
selector: '[kid]'
|
||||||
appInjector: []
|
|
||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
templateUrl: 'kid.html',
|
templateUrl: 'kid.html',
|
||||||
|
@ -348,8 +347,7 @@ class Kid {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[dad]',
|
selector: '[dad]'
|
||||||
appInjector: [Grandpa]
|
|
||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
templateUrl: 'dad.html',
|
templateUrl: 'dad.html',
|
||||||
|
@ -364,7 +362,7 @@ class Dad {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[grandpa]',
|
selector: '[grandpa]',
|
||||||
appInjector: []
|
viewInjector: []
|
||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
templateUrl: 'grandpa.html',
|
templateUrl: 'grandpa.html',
|
||||||
|
|
|
@ -48,7 +48,7 @@ export {URLSearchParams} from 'angular2/src/http/url_search_params';
|
||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
* import {httpInjectables, Http} from 'angular2/http';
|
* import {httpInjectables, Http} from 'angular2/http';
|
||||||
* @Component({selector: 'http-app', appInjector: [httpInjectables]})
|
* @Component({selector: 'http-app', viewInjector: [httpInjectables]})
|
||||||
* @View({template: '{{data}}'})
|
* @View({template: '{{data}}'})
|
||||||
* class MyApp {
|
* class MyApp {
|
||||||
* constructor(http:Http) {
|
* constructor(http:Http) {
|
||||||
|
|
|
@ -822,8 +822,7 @@ export interface DirectiveArgs {
|
||||||
* When a component is instantiated, Angular
|
* When a component is instantiated, Angular
|
||||||
* - creates a shadow DOM for the component.
|
* - creates a shadow DOM for the component.
|
||||||
* - loads the selected template into the shadow DOM.
|
* - loads the selected template into the shadow DOM.
|
||||||
* - creates a child {@link Injector} which is configured with the `appInjector` for the
|
* - creates all the injectable objects configured with `hostInjector` and `viewInjector`.
|
||||||
* {@link Component}.
|
|
||||||
*
|
*
|
||||||
* All template expressions and statements are then evaluated against the component instance.
|
* All template expressions and statements are then evaluated against the component instance.
|
||||||
*
|
*
|
||||||
|
@ -865,59 +864,6 @@ export class Component extends Directive {
|
||||||
*/
|
*/
|
||||||
changeDetection: string;
|
changeDetection: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the set of injectable objects that are visible to a Component and its children.
|
|
||||||
*
|
|
||||||
* The `appInjector` defined in the Component annotation allow you to configure a set of bindings
|
|
||||||
* for the component's
|
|
||||||
* injector.
|
|
||||||
*
|
|
||||||
* When a component is instantiated, Angular creates a new child Injector, which is configured
|
|
||||||
* with the bindings in
|
|
||||||
* the Component `appInjector` annotation. The injectable objects then become available for
|
|
||||||
* injection to the component
|
|
||||||
* itself and any of the directives in the component's template, i.e. they are not available to
|
|
||||||
* the directives which
|
|
||||||
* are children in the component's light DOM.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The syntax for configuring the `appInjector` injectable is identical to {@link Injector}
|
|
||||||
* injectable configuration.
|
|
||||||
* See {@link Injector} for additional detail.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* ## Simple Example
|
|
||||||
*
|
|
||||||
* Here is an example of a class that can be injected:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* class Greeter {
|
|
||||||
* greet(name:string) {
|
|
||||||
* return 'Hello ' + name + '!';
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @Component({
|
|
||||||
* selector: 'greet',
|
|
||||||
* appInjector: [
|
|
||||||
* Greeter
|
|
||||||
* ]
|
|
||||||
* })
|
|
||||||
* @View({
|
|
||||||
* template: `{{greeter.greet('world')}}!`,
|
|
||||||
* directives: [Child]
|
|
||||||
* })
|
|
||||||
* class HelloWorld {
|
|
||||||
* greeter:Greeter;
|
|
||||||
*
|
|
||||||
* constructor(greeter:Greeter) {
|
|
||||||
* this.greeter = greeter;
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
appInjector: List<any>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the set of injectable objects that are visible to its view dom children.
|
* Defines the set of injectable objects that are visible to its view dom children.
|
||||||
*
|
*
|
||||||
|
@ -960,9 +906,8 @@ export class Component extends Directive {
|
||||||
*/
|
*/
|
||||||
viewInjector: List<any>;
|
viewInjector: List<any>;
|
||||||
|
|
||||||
constructor({selector, properties, events, host, exportAs, appInjector, lifecycle, hostInjector,
|
constructor({selector, properties, events, host, exportAs, lifecycle, hostInjector, viewInjector,
|
||||||
viewInjector, changeDetection = DEFAULT,
|
changeDetection = DEFAULT, compileChildren = true}: ComponentArgs = {}) {
|
||||||
compileChildren = true}: ComponentArgs = {}) {
|
|
||||||
super({
|
super({
|
||||||
selector: selector,
|
selector: selector,
|
||||||
properties: properties,
|
properties: properties,
|
||||||
|
@ -975,13 +920,11 @@ export class Component extends Directive {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.changeDetection = changeDetection;
|
this.changeDetection = changeDetection;
|
||||||
this.appInjector = appInjector;
|
|
||||||
this.viewInjector = viewInjector;
|
this.viewInjector = viewInjector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentArgs extends DirectiveArgs {
|
export interface ComponentArgs extends DirectiveArgs {
|
||||||
appInjector?: List<any>;
|
|
||||||
viewInjector?: List<any>;
|
viewInjector?: List<any>;
|
||||||
changeDetection?: string;
|
changeDetection?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,11 +209,9 @@ function _createNgZone(givenReporter: Function): NgZone {
|
||||||
* 1. It uses the component's `selector` property to locate the DOM element which needs to be
|
* 1. It uses the component's `selector` property to locate the DOM element which needs to be
|
||||||
* upgraded into
|
* upgraded into
|
||||||
* the angular component.
|
* the angular component.
|
||||||
* 2. It creates a new child injector (from the platform injector) and configures the injector with
|
* 2. It creates a new child injector (from the platform injector). Optionally, you can also
|
||||||
* the component's
|
* override the injector configuration for an app by
|
||||||
* `appInjector`. Optionally, you can also override the injector configuration for an app by
|
* invoking `bootstrap` with the `componentInjectableBindings` argument.
|
||||||
* invoking
|
|
||||||
* `bootstrap` with the `componentInjectableBindings` argument.
|
|
||||||
* 3. It creates a new `Zone` and connects it to the angular application's change detection domain
|
* 3. It creates a new `Zone` and connects it to the angular application's change detection domain
|
||||||
* instance.
|
* instance.
|
||||||
* 4. It creates a shadow DOM on the selected component's host element and loads the template into
|
* 4. It creates a shadow DOM on the selected component's host element and loads the template into
|
||||||
|
@ -270,9 +268,9 @@ function _createNgZone(givenReporter: Function): NgZone {
|
||||||
* - `appComponentType`: The root component which should act as the application. This is a reference
|
* - `appComponentType`: The root component which should act as the application. This is a reference
|
||||||
* to a `Type`
|
* to a `Type`
|
||||||
* which is annotated with `@Component(...)`.
|
* which is annotated with `@Component(...)`.
|
||||||
* - `componentInjectableBindings`: An additional set of bindings that can be added to `appInjector`
|
* - `componentInjectableBindings`: An additional set of bindings that can be added to the app
|
||||||
* for the
|
* injector
|
||||||
* {@link Component} to override default injection behavior.
|
* to override default injection behavior.
|
||||||
* - `errorReporter`: `function(exception:any, stackTrace:string)` a default error reporter for
|
* - `errorReporter`: `function(exception:any, stackTrace:string)` a default error reporter for
|
||||||
* unhandled exceptions.
|
* unhandled exceptions.
|
||||||
*
|
*
|
||||||
|
|
|
@ -30,8 +30,8 @@ export class DynamicComponentLoader {
|
||||||
* component's selector.
|
* component's selector.
|
||||||
* The loaded component receives injection normally as a hosted view.
|
* The loaded component receives injection normally as a hosted view.
|
||||||
*/
|
*/
|
||||||
loadAsRoot(typeOrBinding: Type | Binding, overrideSelector: string = null,
|
loadAsRoot(typeOrBinding: Type | Binding, overrideSelector: string,
|
||||||
injector: Injector = null): Promise<ComponentRef> {
|
injector: Injector): Promise<ComponentRef> {
|
||||||
return this._compiler.compileInHost(typeOrBinding)
|
return this._compiler.compileInHost(typeOrBinding)
|
||||||
.then(hostProtoViewRef => {
|
.then(hostProtoViewRef => {
|
||||||
var hostViewRef =
|
var hostViewRef =
|
||||||
|
@ -51,10 +51,10 @@ export class DynamicComponentLoader {
|
||||||
* injection normally as a hosted view.
|
* injection normally as a hosted view.
|
||||||
*/
|
*/
|
||||||
loadIntoLocation(typeOrBinding: Type | Binding, hostLocation: ElementRef, anchorName: string,
|
loadIntoLocation(typeOrBinding: Type | Binding, hostLocation: ElementRef, anchorName: string,
|
||||||
injector: Injector = null): Promise<ComponentRef> {
|
bindings: ResolvedBinding[] = null): Promise<ComponentRef> {
|
||||||
return this.loadNextToLocation(
|
return this.loadNextToLocation(
|
||||||
typeOrBinding, this._viewManager.getNamedElementInComponentView(hostLocation, anchorName),
|
typeOrBinding, this._viewManager.getNamedElementInComponentView(hostLocation, anchorName),
|
||||||
injector);
|
bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,12 +62,12 @@ export class DynamicComponentLoader {
|
||||||
* injection normally as a hosted view.
|
* injection normally as a hosted view.
|
||||||
*/
|
*/
|
||||||
loadNextToLocation(typeOrBinding: Type | Binding, location: ElementRef,
|
loadNextToLocation(typeOrBinding: Type | Binding, location: ElementRef,
|
||||||
injector: Injector = null): Promise<ComponentRef> {
|
bindings: ResolvedBinding[] = null): Promise<ComponentRef> {
|
||||||
return this._compiler.compileInHost(typeOrBinding)
|
return this._compiler.compileInHost(typeOrBinding)
|
||||||
.then(hostProtoViewRef => {
|
.then(hostProtoViewRef => {
|
||||||
var viewContainer = this._viewManager.getViewContainer(location);
|
var viewContainer = this._viewManager.getViewContainer(location);
|
||||||
var hostViewRef =
|
var hostViewRef =
|
||||||
viewContainer.create(hostProtoViewRef, viewContainer.length, null, injector);
|
viewContainer.create(hostProtoViewRef, viewContainer.length, null, bindings);
|
||||||
var newLocation = this._viewManager.getHostElement(hostViewRef);
|
var newLocation = this._viewManager.getHostElement(hostViewRef);
|
||||||
var component = this._viewManager.getComponent(newLocation);
|
var component = this._viewManager.getComponent(newLocation);
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,6 @@ import {
|
||||||
PUBLIC,
|
PUBLIC,
|
||||||
PRIVATE,
|
PRIVATE,
|
||||||
undefinedValue,
|
undefinedValue,
|
||||||
InjectorInlineStrategy,
|
|
||||||
InjectorDynamicStrategy,
|
|
||||||
Key,
|
Key,
|
||||||
Dependency,
|
Dependency,
|
||||||
bind,
|
bind,
|
||||||
|
@ -32,6 +30,11 @@ import {
|
||||||
VisibilityAnnotation,
|
VisibilityAnnotation,
|
||||||
self
|
self
|
||||||
} from 'angular2/di';
|
} from 'angular2/di';
|
||||||
|
import {
|
||||||
|
InjectorInlineStrategy,
|
||||||
|
InjectorDynamicStrategy,
|
||||||
|
BindingWithVisibility
|
||||||
|
} from 'angular2/src/di/injector';
|
||||||
|
|
||||||
import {Attribute, Query} from 'angular2/src/core/annotations_impl/di';
|
import {Attribute, Query} from 'angular2/src/core/annotations_impl/di';
|
||||||
|
|
||||||
|
@ -201,7 +204,6 @@ export class DirectiveDependency extends Dependency {
|
||||||
|
|
||||||
export class DirectiveBinding extends ResolvedBinding {
|
export class DirectiveBinding extends ResolvedBinding {
|
||||||
constructor(key: Key, factory: Function, dependencies: List<Dependency>,
|
constructor(key: Key, factory: Function, dependencies: List<Dependency>,
|
||||||
public resolvedAppInjectables: List<ResolvedBinding>,
|
|
||||||
public resolvedHostInjectables: List<ResolvedBinding>,
|
public resolvedHostInjectables: List<ResolvedBinding>,
|
||||||
public resolvedViewInjectables: List<ResolvedBinding>,
|
public resolvedViewInjectables: List<ResolvedBinding>,
|
||||||
public metadata: DirectiveMetadata) {
|
public metadata: DirectiveMetadata) {
|
||||||
|
@ -235,9 +237,6 @@ export class DirectiveBinding extends ResolvedBinding {
|
||||||
|
|
||||||
var rb = binding.resolve();
|
var rb = binding.resolve();
|
||||||
var deps = ListWrapper.map(rb.dependencies, DirectiveDependency.createFrom);
|
var deps = ListWrapper.map(rb.dependencies, DirectiveDependency.createFrom);
|
||||||
var resolvedAppInjectables = ann instanceof Component && isPresent(ann.appInjector) ?
|
|
||||||
Injector.resolve(ann.appInjector) :
|
|
||||||
[];
|
|
||||||
var resolvedHostInjectables =
|
var resolvedHostInjectables =
|
||||||
isPresent(ann.hostInjector) ? resolveBindings(ann.hostInjector) : [];
|
isPresent(ann.hostInjector) ? resolveBindings(ann.hostInjector) : [];
|
||||||
var resolvedViewInjectables = ann instanceof Component && isPresent(ann.viewInjector) ?
|
var resolvedViewInjectables = ann instanceof Component && isPresent(ann.viewInjector) ?
|
||||||
|
@ -265,8 +264,8 @@ export class DirectiveBinding extends ResolvedBinding {
|
||||||
|
|
||||||
exportAs: ann.exportAs
|
exportAs: ann.exportAs
|
||||||
});
|
});
|
||||||
return new DirectiveBinding(rb.key, rb.factory, deps, resolvedAppInjectables,
|
return new DirectiveBinding(rb.key, rb.factory, deps, resolvedHostInjectables,
|
||||||
resolvedHostInjectables, resolvedViewInjectables, metadata);
|
resolvedViewInjectables, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _readAttributes(deps) {
|
static _readAttributes(deps) {
|
||||||
|
@ -313,39 +312,35 @@ export class HostActionAccessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BindingData {
|
function _createEventEmitterAccessors(bwv: BindingWithVisibility): EventEmitterAccessor[] {
|
||||||
constructor(public binding: ResolvedBinding, public visibility: number) {}
|
var binding = bwv.binding;
|
||||||
|
if (!(binding instanceof DirectiveBinding)) return [];
|
||||||
|
var db = <DirectiveBinding>binding;
|
||||||
|
return ListWrapper.map(db.eventEmitters, eventConfig => {
|
||||||
|
let fieldName;
|
||||||
|
let eventName;
|
||||||
|
var colonIdx = eventConfig.indexOf(':');
|
||||||
|
if (colonIdx > -1) {
|
||||||
|
// long format: 'fieldName: eventName'
|
||||||
|
fieldName = StringWrapper.substring(eventConfig, 0, colonIdx).trim();
|
||||||
|
eventName = StringWrapper.substring(eventConfig, colonIdx + 1).trim();
|
||||||
|
} else {
|
||||||
|
// short format: 'name' when fieldName and eventName are the same
|
||||||
|
fieldName = eventName = eventConfig;
|
||||||
|
}
|
||||||
|
return new EventEmitterAccessor(eventName, reflector.getter(fieldName));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getKeyId(): number { return this.binding.key.id; }
|
function _createHostActionAccessors(bwv: BindingWithVisibility): HostActionAccessor[] {
|
||||||
|
var binding = bwv.binding;
|
||||||
createEventEmitterAccessors(): List<EventEmitterAccessor> {
|
if (!(binding instanceof DirectiveBinding)) return [];
|
||||||
if (!(this.binding instanceof DirectiveBinding)) return [];
|
var res = [];
|
||||||
var db = <DirectiveBinding>this.binding;
|
var db = <DirectiveBinding>binding;
|
||||||
return ListWrapper.map(db.eventEmitters, eventConfig => {
|
MapWrapper.forEach(db.hostActions, (actionExpression, actionName) => {
|
||||||
let fieldName;
|
res.push(new HostActionAccessor(actionExpression, reflector.getter(actionName)));
|
||||||
let eventName;
|
});
|
||||||
var colonIdx = eventConfig.indexOf(':');
|
return res;
|
||||||
if (colonIdx > -1) {
|
|
||||||
// long format: 'fieldName: eventName'
|
|
||||||
fieldName = StringWrapper.substring(eventConfig, 0, colonIdx).trim();
|
|
||||||
eventName = StringWrapper.substring(eventConfig, colonIdx + 1).trim();
|
|
||||||
} else {
|
|
||||||
// short format: 'name' when fieldName and eventName are the same
|
|
||||||
fieldName = eventName = eventConfig;
|
|
||||||
}
|
|
||||||
return new EventEmitterAccessor(eventName, reflector.getter(fieldName));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createHostActionAccessors(): HostActionAccessor[] {
|
|
||||||
if (!(this.binding instanceof DirectiveBinding)) return [];
|
|
||||||
var res = [];
|
|
||||||
var db = <DirectiveBinding>this.binding;
|
|
||||||
MapWrapper.forEach(db.hostActions, (actionExpression, actionName) => {
|
|
||||||
res.push(new HostActionAccessor(actionExpression, reflector.getter(actionName)));
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProtoElementInjector {
|
export class ProtoElementInjector {
|
||||||
|
@ -360,62 +355,65 @@ export class ProtoElementInjector {
|
||||||
directiveVariableBindings: Map<string, number>): ProtoElementInjector {
|
directiveVariableBindings: Map<string, number>): ProtoElementInjector {
|
||||||
var bd = [];
|
var bd = [];
|
||||||
|
|
||||||
ProtoElementInjector._createDirectiveBindingData(bindings, bd, firstBindingIsComponent);
|
ProtoElementInjector._createDirectiveBindingWithVisibility(bindings, bd,
|
||||||
|
firstBindingIsComponent);
|
||||||
if (firstBindingIsComponent) {
|
if (firstBindingIsComponent) {
|
||||||
ProtoElementInjector._createViewInjectorBindingData(bindings, bd);
|
ProtoElementInjector._createViewInjectorBindingWithVisibility(bindings, bd);
|
||||||
}
|
}
|
||||||
ProtoElementInjector._createHostInjectorBindingData(bindings, bd, firstBindingIsComponent);
|
ProtoElementInjector._createHostInjectorBindingWithVisibility(bindings, bd,
|
||||||
|
firstBindingIsComponent);
|
||||||
return new ProtoElementInjector(parent, index, bd, distanceToParent, firstBindingIsComponent,
|
return new ProtoElementInjector(parent, index, bd, distanceToParent, firstBindingIsComponent,
|
||||||
directiveVariableBindings);
|
directiveVariableBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createDirectiveBindingData(dirBindings: List<ResolvedBinding>,
|
private static _createDirectiveBindingWithVisibility(dirBindings: List<ResolvedBinding>,
|
||||||
bd: List<BindingData>,
|
bd: BindingWithVisibility[],
|
||||||
firstBindingIsComponent: boolean) {
|
firstBindingIsComponent: boolean) {
|
||||||
ListWrapper.forEach(dirBindings, dirBinding => {
|
ListWrapper.forEach(dirBindings, dirBinding => {
|
||||||
bd.push(ProtoElementInjector._createBindingData(firstBindingIsComponent, dirBinding,
|
bd.push(ProtoElementInjector._createBindingWithVisibility(firstBindingIsComponent, dirBinding,
|
||||||
dirBindings, dirBinding));
|
dirBindings, dirBinding));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createHostInjectorBindingData(dirBindings: List<ResolvedBinding>,
|
private static _createHostInjectorBindingWithVisibility(dirBindings: List<ResolvedBinding>,
|
||||||
bd: List<BindingData>,
|
bd: BindingWithVisibility[],
|
||||||
firstBindingIsComponent: boolean) {
|
firstBindingIsComponent: boolean) {
|
||||||
ListWrapper.forEach(dirBindings, dirBinding => {
|
ListWrapper.forEach(dirBindings, dirBinding => {
|
||||||
ListWrapper.forEach(dirBinding.resolvedHostInjectables, b => {
|
ListWrapper.forEach(dirBinding.resolvedHostInjectables, b => {
|
||||||
bd.push(ProtoElementInjector._createBindingData(firstBindingIsComponent, dirBinding,
|
bd.push(ProtoElementInjector._createBindingWithVisibility(firstBindingIsComponent,
|
||||||
dirBindings, b));
|
dirBinding, dirBindings, b));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createBindingData(firstBindingIsComponent, dirBinding, dirBindings, binding) {
|
private static _createBindingWithVisibility(firstBindingIsComponent, dirBinding, dirBindings,
|
||||||
|
binding) {
|
||||||
var isComponent = firstBindingIsComponent && dirBindings[0] === dirBinding;
|
var isComponent = firstBindingIsComponent && dirBindings[0] === dirBinding;
|
||||||
return new BindingData(binding, isComponent ? PUBLIC_AND_PRIVATE : PUBLIC);
|
return new BindingWithVisibility(binding, isComponent ? PUBLIC_AND_PRIVATE : PUBLIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createViewInjectorBindingData(bindings: List<ResolvedBinding>,
|
private static _createViewInjectorBindingWithVisibility(bindings: List<ResolvedBinding>,
|
||||||
bd: List<BindingData>) {
|
bd: BindingWithVisibility[]) {
|
||||||
var db = <DirectiveBinding>bindings[0];
|
var db = <DirectiveBinding>bindings[0];
|
||||||
ListWrapper.forEach(db.resolvedViewInjectables, b => bd.push(new BindingData(b, PRIVATE)));
|
ListWrapper.forEach(db.resolvedViewInjectables,
|
||||||
|
b => bd.push(new BindingWithVisibility(b, PRIVATE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(public parent: ProtoElementInjector, public index: int, bd: List<BindingData>,
|
constructor(public parent: ProtoElementInjector, public index: int, bwv: BindingWithVisibility[],
|
||||||
public distanceToParent: number, public _firstBindingIsComponent: boolean,
|
public distanceToParent: number, public _firstBindingIsComponent: boolean,
|
||||||
public directiveVariableBindings: Map<string, number>) {
|
public directiveVariableBindings: Map<string, number>) {
|
||||||
var length = bd.length;
|
var length = bwv.length;
|
||||||
|
|
||||||
this.protoInjector =
|
this.protoInjector = new ProtoInjector(bwv, distanceToParent);
|
||||||
new ProtoInjector(isPresent(parent) ? parent.protoInjector : null, bd, distanceToParent);
|
|
||||||
|
|
||||||
this.eventEmitterAccessors = ListWrapper.createFixedSize(length);
|
this.eventEmitterAccessors = ListWrapper.createFixedSize(length);
|
||||||
this.hostActionAccessors = ListWrapper.createFixedSize(length);
|
this.hostActionAccessors = ListWrapper.createFixedSize(length);
|
||||||
|
|
||||||
for (var i = 0; i < length; ++i) {
|
for (var i = 0; i < length; ++i) {
|
||||||
this.eventEmitterAccessors[i] = bd[i].createEventEmitterAccessors();
|
this.eventEmitterAccessors[i] = _createEventEmitterAccessors(bwv[i]);
|
||||||
this.hostActionAccessors[i] = bd[i].createHostActionAccessors();
|
this.hostActionAccessors[i] = _createHostActionAccessors(bwv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,10 +430,7 @@ export class ProtoElementInjector {
|
||||||
|
|
||||||
|
|
||||||
export class ElementInjector extends TreeNode<ElementInjector> {
|
export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
private _lightDomAppInjector: Injector = null;
|
|
||||||
private _shadowDomAppInjector: Injector = null;
|
|
||||||
private _host: ElementInjector;
|
private _host: ElementInjector;
|
||||||
|
|
||||||
private _preBuiltObjects = null;
|
private _preBuiltObjects = null;
|
||||||
|
|
||||||
// Queries are added during construction or linking with a new parent.
|
// Queries are added during construction or linking with a new parent.
|
||||||
|
@ -453,9 +448,10 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
super(parent);
|
super(parent);
|
||||||
|
|
||||||
this._injector = new Injector(this._proto.protoInjector);
|
this._injector = new Injector(this._proto.protoInjector);
|
||||||
|
this._injector.ei = this; // TODO savkin remove after mergin DI and EI
|
||||||
|
|
||||||
// we couple ourselves to the injector strategy to avoid polymoprhic calls
|
// we couple ourselves to the injector strategy to avoid polymoprhic calls
|
||||||
var injectorStrategy = <any>this._injector.strategy;
|
var injectorStrategy = <any>this._injector.internalStrategy;
|
||||||
this._strategy = injectorStrategy instanceof InjectorInlineStrategy ?
|
this._strategy = injectorStrategy instanceof InjectorInlineStrategy ?
|
||||||
new ElementInjectorInlineStrategy(
|
new ElementInjectorInlineStrategy(
|
||||||
injectorStrategy, this) :
|
injectorStrategy, this) :
|
||||||
|
@ -472,10 +468,8 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
this.hydrated = false;
|
this.hydrated = false;
|
||||||
this._host = null;
|
this._host = null;
|
||||||
this._preBuiltObjects = null;
|
this._preBuiltObjects = null;
|
||||||
this._lightDomAppInjector = null;
|
|
||||||
this._shadowDomAppInjector = null;
|
|
||||||
this._strategy.callOnDestroy();
|
this._strategy.callOnDestroy();
|
||||||
this._injector.dehydrate();
|
this._injector.internalStrategy.dehydrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAllChangesDone(): void {
|
onAllChangesDone(): void {
|
||||||
|
@ -490,24 +484,12 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrate(injector: Injector, host: ElementInjector, preBuiltObjects: PreBuiltObjects): void {
|
hydrate(imperativelyCreatedInjector: Injector, host: ElementInjector,
|
||||||
var p = this._proto;
|
preBuiltObjects: PreBuiltObjects): void {
|
||||||
|
|
||||||
this._host = host;
|
this._host = host;
|
||||||
this._lightDomAppInjector = injector;
|
|
||||||
this._preBuiltObjects = preBuiltObjects;
|
this._preBuiltObjects = preBuiltObjects;
|
||||||
|
|
||||||
if (p._firstBindingIsComponent) {
|
this._hydrateInjector(imperativelyCreatedInjector, host);
|
||||||
this._shadowDomAppInjector =
|
|
||||||
this._createShadowDomAppInjector(this._strategy.getComponentBinding(), injector);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._checkShadowDomAppInjector(this._shadowDomAppInjector);
|
|
||||||
|
|
||||||
var parentInjector = isPresent(this._parent) ? this._parent._injector : null;
|
|
||||||
var hostInjector = isPresent(host) ? host._injector : null;
|
|
||||||
|
|
||||||
this._injector.hydrate(parentInjector, hostInjector, this);
|
|
||||||
|
|
||||||
this._addDirectivesToQueries();
|
this._addDirectivesToQueries();
|
||||||
this._addVarBindingsToQueries();
|
this._addVarBindingsToQueries();
|
||||||
|
@ -515,6 +497,59 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
this.hydrated = true;
|
this.hydrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _hydrateInjector(imperativelyCreatedInjector: Injector, host: ElementInjector): void {
|
||||||
|
if (isPresent(this._parent)) {
|
||||||
|
this._reattachInjector(this._injector, this._parent._injector, false);
|
||||||
|
} else {
|
||||||
|
// This injector is at the boundary.
|
||||||
|
//
|
||||||
|
// The injector tree we are assembling:
|
||||||
|
//
|
||||||
|
// host._injector (only if present)
|
||||||
|
// |
|
||||||
|
// |boundary
|
||||||
|
// |
|
||||||
|
// imperativelyCreatedInjector (only if present)
|
||||||
|
// |
|
||||||
|
// |boundary
|
||||||
|
// |
|
||||||
|
// this._injector
|
||||||
|
//
|
||||||
|
|
||||||
|
// host._injector (only if present)
|
||||||
|
// |
|
||||||
|
// |boundary
|
||||||
|
// |
|
||||||
|
// imperativelyCreatedInjector (only if present)
|
||||||
|
if (isPresent(imperativelyCreatedInjector) && isPresent(host)) {
|
||||||
|
this._reattachInjector(imperativelyCreatedInjector, host._injector, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// host._injector OR imperativelyCreatedInjector OR null
|
||||||
|
// |
|
||||||
|
// |boundary
|
||||||
|
// |
|
||||||
|
// this._injector
|
||||||
|
var parent = this._getParentInjector(imperativelyCreatedInjector, host);
|
||||||
|
this._reattachInjector(this._injector, parent, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getParentInjector(injector: Injector, host: ElementInjector): Injector {
|
||||||
|
if (isPresent(injector)) {
|
||||||
|
return injector;
|
||||||
|
} else if (isPresent(host)) {
|
||||||
|
return host._injector;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _reattachInjector(injector: Injector, parentInjector: Injector, isBoundary: boolean) {
|
||||||
|
injector.internalStrategy.attach(parentInjector, isBoundary);
|
||||||
|
injector.internalStrategy.hydrate();
|
||||||
|
}
|
||||||
|
|
||||||
hasVariableBinding(name: string): boolean {
|
hasVariableBinding(name: string): boolean {
|
||||||
var vb = this._proto.directiveVariableBindings;
|
var vb = this._proto.directiveVariableBindings;
|
||||||
return isPresent(vb) && vb.has(name);
|
return isPresent(vb) && vb.has(name);
|
||||||
|
@ -525,25 +560,6 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
return isPresent(index) ? this.getDirectiveAtIndex(<number>index) : this.getElementRef();
|
return isPresent(index) ? this.getDirectiveAtIndex(<number>index) : this.getElementRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createShadowDomAppInjector(componentDirective: DirectiveBinding,
|
|
||||||
appInjector: Injector): Injector {
|
|
||||||
if (!ListWrapper.isEmpty(componentDirective.resolvedAppInjectables)) {
|
|
||||||
return appInjector.createChildFromResolved(componentDirective.resolvedAppInjectables);
|
|
||||||
} else {
|
|
||||||
return appInjector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _checkShadowDomAppInjector(shadowDomAppInjector: Injector): void {
|
|
||||||
if (this._proto._firstBindingIsComponent && isBlank(shadowDomAppInjector)) {
|
|
||||||
throw new BaseException(
|
|
||||||
'A shadowDomAppInjector is required as this ElementInjector contains a component');
|
|
||||||
} else if (!this._proto._firstBindingIsComponent && isPresent(shadowDomAppInjector)) {
|
|
||||||
throw new BaseException(
|
|
||||||
'No shadowDomAppInjector allowed as there is not component stored in this ElementInjector');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get(token): any { return this._injector.get(token); }
|
get(token): any { return this._injector.get(token); }
|
||||||
|
|
||||||
hasDirective(type: Type): boolean { return isPresent(this._injector.getOptional(type)); }
|
hasDirective(type: Type): boolean { return isPresent(this._injector.getOptional(type)); }
|
||||||
|
@ -573,7 +589,7 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
isComponentKey(key: Key): boolean { return this._strategy.isComponentKey(key); }
|
isComponentKey(key: Key): boolean { return this._strategy.isComponentKey(key); }
|
||||||
|
|
||||||
getDependency(dep: any): any {
|
getDependency(dep: any): any {
|
||||||
var key = dep.key;
|
var key: Key = dep.key;
|
||||||
|
|
||||||
if (!(dep instanceof DirectiveDependency)) return undefinedValue;
|
if (!(dep instanceof DirectiveDependency)) return undefinedValue;
|
||||||
|
|
||||||
|
@ -802,22 +818,10 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
||||||
if (this._query2 == query) this._query2 = null;
|
if (this._query2 == query) this._query2 = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
appInjector(requestor: Key): Injector {
|
getDirectiveAtIndex(index: number): any { return this._injector.getAt(index); }
|
||||||
if (isPresent(requestor) && this.isComponentKey(requestor)) {
|
|
||||||
return this._shadowDomAppInjector;
|
|
||||||
} else {
|
|
||||||
return this._lightDomAppInjector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirectiveAtIndex(index: number): any { return this._injector.getObjAtIndex(index); }
|
|
||||||
|
|
||||||
hasInstances(): boolean { return this._proto.hasBindings && this.hydrated; }
|
hasInstances(): boolean { return this._proto.hasBindings && this.hydrated; }
|
||||||
|
|
||||||
getLightDomAppInjector(): Injector { return this._lightDomAppInjector; }
|
|
||||||
|
|
||||||
getShadowDomAppInjector(): Injector { return this._shadowDomAppInjector; }
|
|
||||||
|
|
||||||
getHost(): ElementInjector { return this._host; }
|
getHost(): ElementInjector { return this._host; }
|
||||||
|
|
||||||
getBoundElementIndex(): number { return this._proto.index; }
|
getBoundElementIndex(): number { return this._proto.index; }
|
||||||
|
|
|
@ -348,7 +348,7 @@ function _findParentProtoElementInjectorWithDistance(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (binderIndex !== -1);
|
} while (binderIndex !== -1);
|
||||||
return new ParentProtoElementInjectorWithDistance(null, -1);
|
return new ParentProtoElementInjectorWithDistance(null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createProtoElementInjector(binderIndex, parentPeiWithDistance, renderElementBinder,
|
function _createProtoElementInjector(binderIndex, parentPeiWithDistance, renderElementBinder,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {ListWrapper, List} from 'angular2/src/facade/collection';
|
import {ListWrapper, List} from 'angular2/src/facade/collection';
|
||||||
import {Injector} from 'angular2/di';
|
import {ResolvedBinding} from 'angular2/di';
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import * as avmModule from './view_manager';
|
import * as avmModule from './view_manager';
|
||||||
|
@ -31,10 +31,10 @@ export class ViewContainerRef {
|
||||||
// TODO(rado): profile and decide whether bounds checks should be added
|
// TODO(rado): profile and decide whether bounds checks should be added
|
||||||
// to the methods below.
|
// to the methods below.
|
||||||
create(protoViewRef: ProtoViewRef = null, atIndex: number = -1, context: ElementRef = null,
|
create(protoViewRef: ProtoViewRef = null, atIndex: number = -1, context: ElementRef = null,
|
||||||
injector: Injector = null): ViewRef {
|
bindings: ResolvedBinding[] = null): ViewRef {
|
||||||
if (atIndex == -1) atIndex = this.length;
|
if (atIndex == -1) atIndex = this.length;
|
||||||
return this.viewManager.createViewInContainer(this.element, atIndex, protoViewRef, context,
|
return this.viewManager.createViewInContainer(this.element, atIndex, protoViewRef, context,
|
||||||
injector);
|
bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
insert(viewRef: ViewRef, atIndex: number = -1): ViewRef {
|
insert(viewRef: ViewRef, atIndex: number = -1): ViewRef {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Injector, Binding, Injectable} from 'angular2/di';
|
import {Injector, Binding, Injectable, ResolvedBinding} from 'angular2/di';
|
||||||
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
||||||
import * as viewModule from './view';
|
import * as viewModule from './view';
|
||||||
import {ElementRef} from './element_ref';
|
import {ElementRef} from './element_ref';
|
||||||
|
@ -73,6 +73,7 @@ export class AppViewManager {
|
||||||
|
|
||||||
this._utils.hydrateRootHostView(hostView, injector);
|
this._utils.hydrateRootHostView(hostView, injector);
|
||||||
this._viewHydrateRecurse(hostView);
|
this._viewHydrateRecurse(hostView);
|
||||||
|
|
||||||
return hostView.ref;
|
return hostView.ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +90,7 @@ export class AppViewManager {
|
||||||
|
|
||||||
createViewInContainer(viewContainerLocation: ElementRef, atIndex: number,
|
createViewInContainer(viewContainerLocation: ElementRef, atIndex: number,
|
||||||
protoViewRef: ProtoViewRef, context: ElementRef = null,
|
protoViewRef: ProtoViewRef, context: ElementRef = null,
|
||||||
injector: Injector = null): ViewRef {
|
bindings: ResolvedBinding[] = null): ViewRef {
|
||||||
var protoView = internalProtoView(protoViewRef);
|
var protoView = internalProtoView(protoViewRef);
|
||||||
var parentView = internalView(viewContainerLocation.parentView);
|
var parentView = internalView(viewContainerLocation.parentView);
|
||||||
var boundElementIndex = viewContainerLocation.boundElementIndex;
|
var boundElementIndex = viewContainerLocation.boundElementIndex;
|
||||||
|
@ -106,7 +107,7 @@ export class AppViewManager {
|
||||||
this._utils.attachViewInContainer(parentView, boundElementIndex, contextView,
|
this._utils.attachViewInContainer(parentView, boundElementIndex, contextView,
|
||||||
contextBoundElementIndex, atIndex, view);
|
contextBoundElementIndex, atIndex, view);
|
||||||
this._utils.hydrateViewInContainer(parentView, boundElementIndex, contextView,
|
this._utils.hydrateViewInContainer(parentView, boundElementIndex, contextView,
|
||||||
contextBoundElementIndex, atIndex, injector);
|
contextBoundElementIndex, atIndex, bindings);
|
||||||
this._viewHydrateRecurse(view);
|
this._viewHydrateRecurse(view);
|
||||||
return view.ref;
|
return view.ref;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Injector, Binding, Injectable} from 'angular2/di';
|
import {Injector, Binding, Injectable, ResolvedBinding} from 'angular2/di';
|
||||||
import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
|
||||||
import * as eli from './element_injector';
|
import * as eli from './element_injector';
|
||||||
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
||||||
|
@ -74,15 +74,14 @@ export class AppViewManagerUtils {
|
||||||
hostView.componentChildViews[boundElementIndex] = null;
|
hostView.componentChildViews[boundElementIndex] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrateComponentView(hostView: viewModule.AppView, boundElementIndex: number,
|
hydrateComponentView(hostView: viewModule.AppView, boundElementIndex: number) {
|
||||||
injector: Injector = null) {
|
|
||||||
var elementInjector = hostView.elementInjectors[boundElementIndex];
|
var elementInjector = hostView.elementInjectors[boundElementIndex];
|
||||||
var componentView = hostView.componentChildViews[boundElementIndex];
|
var componentView = hostView.componentChildViews[boundElementIndex];
|
||||||
var component = this.getComponentInstance(hostView, boundElementIndex);
|
var component = this.getComponentInstance(hostView, boundElementIndex);
|
||||||
this._hydrateView(componentView, injector, elementInjector, component, null);
|
this._hydrateView(componentView, null, elementInjector, component, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrateRootHostView(hostView: viewModule.AppView, injector: Injector = null) {
|
hydrateRootHostView(hostView: viewModule.AppView, injector: Injector) {
|
||||||
this._hydrateView(hostView, injector, null, new Object(), null);
|
this._hydrateView(hostView, injector, null, new Object(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +131,7 @@ export class AppViewManagerUtils {
|
||||||
|
|
||||||
hydrateViewInContainer(parentView: viewModule.AppView, boundElementIndex: number,
|
hydrateViewInContainer(parentView: viewModule.AppView, boundElementIndex: number,
|
||||||
contextView: viewModule.AppView, contextBoundElementIndex: number,
|
contextView: viewModule.AppView, contextBoundElementIndex: number,
|
||||||
atIndex: number, injector: Injector) {
|
atIndex: number, bindings: ResolvedBinding[]) {
|
||||||
if (isBlank(contextView)) {
|
if (isBlank(contextView)) {
|
||||||
contextView = parentView;
|
contextView = parentView;
|
||||||
contextBoundElementIndex = boundElementIndex;
|
contextBoundElementIndex = boundElementIndex;
|
||||||
|
@ -140,21 +139,15 @@ export class AppViewManagerUtils {
|
||||||
var viewContainer = parentView.viewContainers[boundElementIndex];
|
var viewContainer = parentView.viewContainers[boundElementIndex];
|
||||||
var view = viewContainer.views[atIndex];
|
var view = viewContainer.views[atIndex];
|
||||||
var elementInjector = contextView.elementInjectors[contextBoundElementIndex];
|
var elementInjector = contextView.elementInjectors[contextBoundElementIndex];
|
||||||
if (isBlank(elementInjector.getHost()) && isBlank(injector)) {
|
|
||||||
injector = elementInjector.getShadowDomAppInjector();
|
var injector = isPresent(bindings) ? Injector.fromResolvedBindings(bindings) : null;
|
||||||
}
|
|
||||||
this._hydrateView(view, injector, elementInjector.getHost(), contextView.context,
|
this._hydrateView(view, injector, elementInjector.getHost(), contextView.context,
|
||||||
contextView.locals);
|
contextView.locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
_hydrateView(view: viewModule.AppView, appInjector: Injector,
|
_hydrateView(view: viewModule.AppView, injector: Injector,
|
||||||
hostElementInjector: eli.ElementInjector, context: Object, parentLocals: Locals) {
|
hostElementInjector: eli.ElementInjector, context: Object, parentLocals: Locals) {
|
||||||
if (isBlank(appInjector)) {
|
|
||||||
appInjector = hostElementInjector.getShadowDomAppInjector();
|
|
||||||
}
|
|
||||||
if (isBlank(appInjector)) {
|
|
||||||
appInjector = hostElementInjector.getLightDomAppInjector();
|
|
||||||
}
|
|
||||||
view.context = context;
|
view.context = context;
|
||||||
view.locals.parent = parentLocals;
|
view.locals.parent = parentLocals;
|
||||||
|
|
||||||
|
@ -163,7 +156,7 @@ export class AppViewManagerUtils {
|
||||||
var elementInjector = view.elementInjectors[i];
|
var elementInjector = view.elementInjectors[i];
|
||||||
|
|
||||||
if (isPresent(elementInjector)) {
|
if (isPresent(elementInjector)) {
|
||||||
elementInjector.hydrate(appInjector, hostElementInjector, view.preBuiltObjects[i]);
|
elementInjector.hydrate(injector, hostElementInjector, view.preBuiltObjects[i]);
|
||||||
this._populateViewLocals(view, elementInjector);
|
this._populateViewLocals(view, elementInjector);
|
||||||
this._setUpEventEmitters(view, elementInjector, i);
|
this._setUpEventEmitters(view, elementInjector, i);
|
||||||
this._setUpHostActions(view, elementInjector, i);
|
this._setUpHostActions(view, elementInjector, i);
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
* ```javascript
|
* ```javascript
|
||||||
* @Component({
|
* @Component({
|
||||||
* selector: 'my-app',
|
* selector: 'my-app',
|
||||||
* appInjector: [
|
* viewInjector: [
|
||||||
* bind(ExceptionHandler).toClass(MyExceptionHandler)
|
* bind(ExceptionHandler).toClass(MyExceptionHandler)
|
||||||
* ]
|
* ]
|
||||||
* })
|
* })
|
||||||
|
|
|
@ -97,16 +97,14 @@ export class Injectable {
|
||||||
* @exportedAs angular2/di_annotations
|
* @exportedAs angular2/di_annotations
|
||||||
*/
|
*/
|
||||||
@CONST()
|
@CONST()
|
||||||
export class Visibility extends DependencyAnnotation {
|
export class Visibility {
|
||||||
constructor(public depth: number, public crossComponentBoundaries: boolean,
|
constructor(public depth: number, public crossBoundaries: boolean, public _includeSelf: boolean) {
|
||||||
public _includeSelf: boolean) {
|
|
||||||
super();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get includeSelf(): boolean { return isBlank(this._includeSelf) ? false : this._includeSelf; }
|
get includeSelf(): boolean { return isBlank(this._includeSelf) ? false : this._includeSelf; }
|
||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
return `@Visibility(depth: ${this.depth}, crossComponentBoundaries: ${this.crossComponentBoundaries}, includeSelf: ${this.includeSelf}})`;
|
return `@Visibility(depth: ${this.depth}, crossBoundaries: ${this.crossBoundaries}, includeSelf: ${this.includeSelf}})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/// <reference path="../../typings/es6-promise/es6-promise.d.ts" />
|
/// <reference path="../../typings/es6-promise/es6-promise.d.ts" />
|
||||||
|
|
||||||
import {Map, List, MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
import {Map, List, MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {ResolvedBinding, Binding, BindingBuilder, bind} from './binding';
|
import {ResolvedBinding, Binding, Dependency, BindingBuilder, bind} from './binding';
|
||||||
import {
|
import {
|
||||||
AbstractBindingError,
|
AbstractBindingError,
|
||||||
NoBindingError,
|
NoBindingError,
|
||||||
|
@ -14,7 +14,7 @@ import {
|
||||||
import {FunctionWrapper, Type, isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {FunctionWrapper, Type, isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {Key} from './key';
|
import {Key} from './key';
|
||||||
import {resolveForwardRef} from './forward_ref';
|
import {resolveForwardRef} from './forward_ref';
|
||||||
import {self, unbounded} from './annotations_impl';
|
import {Visibility, unbounded} from './annotations_impl';
|
||||||
|
|
||||||
const _constructing = CONST_EXPR(new Object());
|
const _constructing = CONST_EXPR(new Object());
|
||||||
const _notFound = CONST_EXPR(new Object());
|
const _notFound = CONST_EXPR(new Object());
|
||||||
|
@ -67,58 +67,58 @@ export class ProtoInjectorInlineStrategy implements ProtoInjectorStrategy {
|
||||||
visibility8: number = null;
|
visibility8: number = null;
|
||||||
visibility9: number = null;
|
visibility9: number = null;
|
||||||
|
|
||||||
constructor(protoEI: ProtoInjector, bd: any[]) {
|
constructor(protoEI: ProtoInjector, bwv: BindingWithVisibility[]) {
|
||||||
var length = bd.length;
|
var length = bwv.length;
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
this.binding0 = bd[0].binding;
|
this.binding0 = bwv[0].binding;
|
||||||
this.keyId0 = bd[0].getKeyId();
|
this.keyId0 = bwv[0].getKeyId();
|
||||||
this.visibility0 = bd[0].visibility;
|
this.visibility0 = bwv[0].visibility;
|
||||||
}
|
}
|
||||||
if (length > 1) {
|
if (length > 1) {
|
||||||
this.binding1 = bd[1].binding;
|
this.binding1 = bwv[1].binding;
|
||||||
this.keyId1 = bd[1].getKeyId();
|
this.keyId1 = bwv[1].getKeyId();
|
||||||
this.visibility1 = bd[1].visibility;
|
this.visibility1 = bwv[1].visibility;
|
||||||
}
|
}
|
||||||
if (length > 2) {
|
if (length > 2) {
|
||||||
this.binding2 = bd[2].binding;
|
this.binding2 = bwv[2].binding;
|
||||||
this.keyId2 = bd[2].getKeyId();
|
this.keyId2 = bwv[2].getKeyId();
|
||||||
this.visibility2 = bd[2].visibility;
|
this.visibility2 = bwv[2].visibility;
|
||||||
}
|
}
|
||||||
if (length > 3) {
|
if (length > 3) {
|
||||||
this.binding3 = bd[3].binding;
|
this.binding3 = bwv[3].binding;
|
||||||
this.keyId3 = bd[3].getKeyId();
|
this.keyId3 = bwv[3].getKeyId();
|
||||||
this.visibility3 = bd[3].visibility;
|
this.visibility3 = bwv[3].visibility;
|
||||||
}
|
}
|
||||||
if (length > 4) {
|
if (length > 4) {
|
||||||
this.binding4 = bd[4].binding;
|
this.binding4 = bwv[4].binding;
|
||||||
this.keyId4 = bd[4].getKeyId();
|
this.keyId4 = bwv[4].getKeyId();
|
||||||
this.visibility4 = bd[4].visibility;
|
this.visibility4 = bwv[4].visibility;
|
||||||
}
|
}
|
||||||
if (length > 5) {
|
if (length > 5) {
|
||||||
this.binding5 = bd[5].binding;
|
this.binding5 = bwv[5].binding;
|
||||||
this.keyId5 = bd[5].getKeyId();
|
this.keyId5 = bwv[5].getKeyId();
|
||||||
this.visibility5 = bd[5].visibility;
|
this.visibility5 = bwv[5].visibility;
|
||||||
}
|
}
|
||||||
if (length > 6) {
|
if (length > 6) {
|
||||||
this.binding6 = bd[6].binding;
|
this.binding6 = bwv[6].binding;
|
||||||
this.keyId6 = bd[6].getKeyId();
|
this.keyId6 = bwv[6].getKeyId();
|
||||||
this.visibility6 = bd[6].visibility;
|
this.visibility6 = bwv[6].visibility;
|
||||||
}
|
}
|
||||||
if (length > 7) {
|
if (length > 7) {
|
||||||
this.binding7 = bd[7].binding;
|
this.binding7 = bwv[7].binding;
|
||||||
this.keyId7 = bd[7].getKeyId();
|
this.keyId7 = bwv[7].getKeyId();
|
||||||
this.visibility7 = bd[7].visibility;
|
this.visibility7 = bwv[7].visibility;
|
||||||
}
|
}
|
||||||
if (length > 8) {
|
if (length > 8) {
|
||||||
this.binding8 = bd[8].binding;
|
this.binding8 = bwv[8].binding;
|
||||||
this.keyId8 = bd[8].getKeyId();
|
this.keyId8 = bwv[8].getKeyId();
|
||||||
this.visibility8 = bd[8].visibility;
|
this.visibility8 = bwv[8].visibility;
|
||||||
}
|
}
|
||||||
if (length > 9) {
|
if (length > 9) {
|
||||||
this.binding9 = bd[9].binding;
|
this.binding9 = bwv[9].binding;
|
||||||
this.keyId9 = bd[9].getKeyId();
|
this.keyId9 = bwv[9].getKeyId();
|
||||||
this.visibility9 = bd[9].visibility;
|
this.visibility9 = bwv[9].visibility;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,17 +146,17 @@ export class ProtoInjectorDynamicStrategy implements ProtoInjectorStrategy {
|
||||||
keyIds: number[];
|
keyIds: number[];
|
||||||
visibilities: number[];
|
visibilities: number[];
|
||||||
|
|
||||||
constructor(protoInj: ProtoInjector, bd: any[]) {
|
constructor(protoInj: ProtoInjector, bwv: BindingWithVisibility[]) {
|
||||||
var len = bd.length;
|
var len = bwv.length;
|
||||||
|
|
||||||
this.bindings = ListWrapper.createFixedSize(len);
|
this.bindings = ListWrapper.createFixedSize(len);
|
||||||
this.keyIds = ListWrapper.createFixedSize(len);
|
this.keyIds = ListWrapper.createFixedSize(len);
|
||||||
this.visibilities = ListWrapper.createFixedSize(len);
|
this.visibilities = ListWrapper.createFixedSize(len);
|
||||||
|
|
||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
this.bindings[i] = bd[i].binding;
|
this.bindings[i] = bwv[i].binding;
|
||||||
this.keyIds[i] = bd[i].getKeyId();
|
this.keyIds[i] = bwv[i].getKeyId();
|
||||||
this.visibilities[i] = bd[i].visibility;
|
this.visibilities[i] = bwv[i].visibility;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,10 +175,10 @@ export class ProtoInjectorDynamicStrategy implements ProtoInjectorStrategy {
|
||||||
export class ProtoInjector {
|
export class ProtoInjector {
|
||||||
_strategy: ProtoInjectorStrategy;
|
_strategy: ProtoInjectorStrategy;
|
||||||
|
|
||||||
constructor(public parent: ProtoInjector, rb: any[], public distanceToParent: number) {
|
constructor(bwv: BindingWithVisibility[], public distanceToParent: number) {
|
||||||
this._strategy = rb.length > _MAX_CONSTRUCTION_COUNTER ?
|
this._strategy = bwv.length > _MAX_CONSTRUCTION_COUNTER ?
|
||||||
new ProtoInjectorDynamicStrategy(this, rb) :
|
new ProtoInjectorDynamicStrategy(this, bwv) :
|
||||||
new ProtoInjectorInlineStrategy(this, rb);
|
new ProtoInjectorInlineStrategy(this, bwv);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBindingAtIndex(index: number): any { return this._strategy.getBindingAtIndex(index); }
|
getBindingAtIndex(index: number): any { return this._strategy.getBindingAtIndex(index); }
|
||||||
|
@ -191,6 +191,7 @@ export interface InjectorStrategy {
|
||||||
getObjAtIndex(index: number): any;
|
getObjAtIndex(index: number): any;
|
||||||
getMaxNumberOfObjects(): number;
|
getMaxNumberOfObjects(): number;
|
||||||
|
|
||||||
|
attach(parent: Injector, isBoundary: boolean): void;
|
||||||
hydrate(): void;
|
hydrate(): void;
|
||||||
dehydrate(): void;
|
dehydrate(): void;
|
||||||
}
|
}
|
||||||
|
@ -213,16 +214,25 @@ export class InjectorInlineStrategy implements InjectorStrategy {
|
||||||
var p = this.protoStrategy;
|
var p = this.protoStrategy;
|
||||||
var inj = this.injector;
|
var inj = this.injector;
|
||||||
|
|
||||||
if (isPresent(p.keyId0) && isBlank(this.obj0)) this.obj0 = inj._new(p.binding0);
|
inj._constructionCounter = 0;
|
||||||
if (isPresent(p.keyId1) && isBlank(this.obj1)) this.obj1 = inj._new(p.binding1);
|
|
||||||
if (isPresent(p.keyId2) && isBlank(this.obj2)) this.obj2 = inj._new(p.binding2);
|
|
||||||
if (isPresent(p.keyId3) && isBlank(this.obj3)) this.obj3 = inj._new(p.binding3);
|
if (isPresent(p.keyId0) && isBlank(this.obj0)) this.obj0 = inj._new(p.binding0, p.visibility0);
|
||||||
if (isPresent(p.keyId4) && isBlank(this.obj4)) this.obj4 = inj._new(p.binding4);
|
if (isPresent(p.keyId1) && isBlank(this.obj1)) this.obj1 = inj._new(p.binding1, p.visibility1);
|
||||||
if (isPresent(p.keyId5) && isBlank(this.obj5)) this.obj5 = inj._new(p.binding5);
|
if (isPresent(p.keyId2) && isBlank(this.obj2)) this.obj2 = inj._new(p.binding2, p.visibility2);
|
||||||
if (isPresent(p.keyId6) && isBlank(this.obj6)) this.obj6 = inj._new(p.binding6);
|
if (isPresent(p.keyId3) && isBlank(this.obj3)) this.obj3 = inj._new(p.binding3, p.visibility3);
|
||||||
if (isPresent(p.keyId7) && isBlank(this.obj7)) this.obj7 = inj._new(p.binding7);
|
if (isPresent(p.keyId4) && isBlank(this.obj4)) this.obj4 = inj._new(p.binding4, p.visibility4);
|
||||||
if (isPresent(p.keyId8) && isBlank(this.obj8)) this.obj8 = inj._new(p.binding8);
|
if (isPresent(p.keyId5) && isBlank(this.obj5)) this.obj5 = inj._new(p.binding5, p.visibility5);
|
||||||
if (isPresent(p.keyId9) && isBlank(this.obj9)) this.obj9 = inj._new(p.binding9);
|
if (isPresent(p.keyId6) && isBlank(this.obj6)) this.obj6 = inj._new(p.binding6, p.visibility6);
|
||||||
|
if (isPresent(p.keyId7) && isBlank(this.obj7)) this.obj7 = inj._new(p.binding7, p.visibility7);
|
||||||
|
if (isPresent(p.keyId8) && isBlank(this.obj8)) this.obj8 = inj._new(p.binding8, p.visibility8);
|
||||||
|
if (isPresent(p.keyId9) && isBlank(this.obj9)) this.obj9 = inj._new(p.binding9, p.visibility9);
|
||||||
|
}
|
||||||
|
|
||||||
|
attach(parent: Injector, isBoundary: boolean): void {
|
||||||
|
var inj = this.injector;
|
||||||
|
inj._parent = parent;
|
||||||
|
inj._isBoundary = isBoundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
dehydrate() {
|
dehydrate() {
|
||||||
|
@ -244,61 +254,61 @@ export class InjectorInlineStrategy implements InjectorStrategy {
|
||||||
|
|
||||||
if (p.keyId0 === keyId && (p.visibility0 & visibility) > 0) {
|
if (p.keyId0 === keyId && (p.visibility0 & visibility) > 0) {
|
||||||
if (isBlank(this.obj0)) {
|
if (isBlank(this.obj0)) {
|
||||||
this.obj0 = inj._new(p.binding0);
|
this.obj0 = inj._new(p.binding0, p.visibility0);
|
||||||
}
|
}
|
||||||
return this.obj0;
|
return this.obj0;
|
||||||
}
|
}
|
||||||
if (p.keyId1 === keyId && (p.visibility1 & visibility) > 0) {
|
if (p.keyId1 === keyId && (p.visibility1 & visibility) > 0) {
|
||||||
if (isBlank(this.obj1)) {
|
if (isBlank(this.obj1)) {
|
||||||
this.obj1 = inj._new(p.binding1);
|
this.obj1 = inj._new(p.binding1, p.visibility1);
|
||||||
}
|
}
|
||||||
return this.obj1;
|
return this.obj1;
|
||||||
}
|
}
|
||||||
if (p.keyId2 === keyId && (p.visibility2 & visibility) > 0) {
|
if (p.keyId2 === keyId && (p.visibility2 & visibility) > 0) {
|
||||||
if (isBlank(this.obj2)) {
|
if (isBlank(this.obj2)) {
|
||||||
this.obj2 = inj._new(p.binding2);
|
this.obj2 = inj._new(p.binding2, p.visibility2);
|
||||||
}
|
}
|
||||||
return this.obj2;
|
return this.obj2;
|
||||||
}
|
}
|
||||||
if (p.keyId3 === keyId && (p.visibility3 & visibility) > 0) {
|
if (p.keyId3 === keyId && (p.visibility3 & visibility) > 0) {
|
||||||
if (isBlank(this.obj3)) {
|
if (isBlank(this.obj3)) {
|
||||||
this.obj3 = inj._new(p.binding3);
|
this.obj3 = inj._new(p.binding3, p.visibility3);
|
||||||
}
|
}
|
||||||
return this.obj3;
|
return this.obj3;
|
||||||
}
|
}
|
||||||
if (p.keyId4 === keyId && (p.visibility4 & visibility) > 0) {
|
if (p.keyId4 === keyId && (p.visibility4 & visibility) > 0) {
|
||||||
if (isBlank(this.obj4)) {
|
if (isBlank(this.obj4)) {
|
||||||
this.obj4 = inj._new(p.binding4);
|
this.obj4 = inj._new(p.binding4, p.visibility4);
|
||||||
}
|
}
|
||||||
return this.obj4;
|
return this.obj4;
|
||||||
}
|
}
|
||||||
if (p.keyId5 === keyId && (p.visibility5 & visibility) > 0) {
|
if (p.keyId5 === keyId && (p.visibility5 & visibility) > 0) {
|
||||||
if (isBlank(this.obj5)) {
|
if (isBlank(this.obj5)) {
|
||||||
this.obj5 = inj._new(p.binding5);
|
this.obj5 = inj._new(p.binding5, p.visibility5);
|
||||||
}
|
}
|
||||||
return this.obj5;
|
return this.obj5;
|
||||||
}
|
}
|
||||||
if (p.keyId6 === keyId && (p.visibility6 & visibility) > 0) {
|
if (p.keyId6 === keyId && (p.visibility6 & visibility) > 0) {
|
||||||
if (isBlank(this.obj6)) {
|
if (isBlank(this.obj6)) {
|
||||||
this.obj6 = inj._new(p.binding6);
|
this.obj6 = inj._new(p.binding6, p.visibility6);
|
||||||
}
|
}
|
||||||
return this.obj6;
|
return this.obj6;
|
||||||
}
|
}
|
||||||
if (p.keyId7 === keyId && (p.visibility7 & visibility) > 0) {
|
if (p.keyId7 === keyId && (p.visibility7 & visibility) > 0) {
|
||||||
if (isBlank(this.obj7)) {
|
if (isBlank(this.obj7)) {
|
||||||
this.obj7 = inj._new(p.binding7);
|
this.obj7 = inj._new(p.binding7, p.visibility7);
|
||||||
}
|
}
|
||||||
return this.obj7;
|
return this.obj7;
|
||||||
}
|
}
|
||||||
if (p.keyId8 === keyId && (p.visibility8 & visibility) > 0) {
|
if (p.keyId8 === keyId && (p.visibility8 & visibility) > 0) {
|
||||||
if (isBlank(this.obj8)) {
|
if (isBlank(this.obj8)) {
|
||||||
this.obj8 = inj._new(p.binding8);
|
this.obj8 = inj._new(p.binding8, p.visibility8);
|
||||||
}
|
}
|
||||||
return this.obj8;
|
return this.obj8;
|
||||||
}
|
}
|
||||||
if (p.keyId9 === keyId && (p.visibility9 & visibility) > 0) {
|
if (p.keyId9 === keyId && (p.visibility9 & visibility) > 0) {
|
||||||
if (isBlank(this.obj9)) {
|
if (isBlank(this.obj9)) {
|
||||||
this.obj9 = inj._new(p.binding9);
|
this.obj9 = inj._new(p.binding9, p.visibility9);
|
||||||
}
|
}
|
||||||
return this.obj9;
|
return this.obj9;
|
||||||
}
|
}
|
||||||
|
@ -335,11 +345,17 @@ export class InjectorDynamicStrategy implements InjectorStrategy {
|
||||||
var p = this.protoStrategy;
|
var p = this.protoStrategy;
|
||||||
for (var i = 0; i < p.keyIds.length; i++) {
|
for (var i = 0; i < p.keyIds.length; i++) {
|
||||||
if (isPresent(p.keyIds[i]) && isBlank(this.objs[i])) {
|
if (isPresent(p.keyIds[i]) && isBlank(this.objs[i])) {
|
||||||
this.objs[i] = this.injector._new(p.bindings[i]);
|
this.objs[i] = this.injector._new(p.bindings[i], p.visibilities[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attach(parent: Injector, isBoundary: boolean): void {
|
||||||
|
var inj = this.injector;
|
||||||
|
inj._parent = parent;
|
||||||
|
inj._isBoundary = isBoundary;
|
||||||
|
}
|
||||||
|
|
||||||
dehydrate(): void { ListWrapper.fill(this.objs, null); }
|
dehydrate(): void { ListWrapper.fill(this.objs, null); }
|
||||||
|
|
||||||
getObjByKeyId(keyId: number, visibility: number): any {
|
getObjByKeyId(keyId: number, visibility: number): any {
|
||||||
|
@ -348,7 +364,7 @@ export class InjectorDynamicStrategy implements InjectorStrategy {
|
||||||
for (var i = 0; i < p.keyIds.length; i++) {
|
for (var i = 0; i < p.keyIds.length; i++) {
|
||||||
if (p.keyIds[i] === keyId && (p.visibilities[i] & visibility) > 0) {
|
if (p.keyIds[i] === keyId && (p.visibilities[i] & visibility) > 0) {
|
||||||
if (isBlank(this.objs[i])) {
|
if (isBlank(this.objs[i])) {
|
||||||
this.objs[i] = this.injector._new(p.bindings[i]);
|
this.objs[i] = this.injector._new(p.bindings[i], p.visibilities[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.objs[i];
|
return this.objs[i];
|
||||||
|
@ -369,7 +385,7 @@ export class InjectorDynamicStrategy implements InjectorStrategy {
|
||||||
getMaxNumberOfObjects(): number { return this.objs.length; }
|
getMaxNumberOfObjects(): number { return this.objs.length; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BindingData {
|
export class BindingWithVisibility {
|
||||||
constructor(public binding: ResolvedBinding, public visibility: number){};
|
constructor(public binding: ResolvedBinding, public visibility: number){};
|
||||||
|
|
||||||
getKeyId(): number { return this.binding.key.id; }
|
getKeyId(): number { return this.binding.key.id; }
|
||||||
|
@ -449,15 +465,10 @@ export class Injector {
|
||||||
* @param `bindings` can be a list of `Type`, {@link Binding}, {@link ResolvedBinding}, or a
|
* @param `bindings` can be a list of `Type`, {@link Binding}, {@link ResolvedBinding}, or a
|
||||||
*recursive list of more
|
*recursive list of more
|
||||||
* bindings.
|
* bindings.
|
||||||
* @param `defaultBindings` Setting to true will auto-create bindings.
|
|
||||||
*/
|
*/
|
||||||
static resolveAndCreate(bindings: List<Type | Binding | List<any>>,
|
static resolveAndCreate(bindings: List<Type | Binding | List<any>>): Injector {
|
||||||
{defaultBindings = false}: any = {}): Injector {
|
|
||||||
var resolvedBindings = Injector.resolve(bindings);
|
var resolvedBindings = Injector.resolve(bindings);
|
||||||
var bd = resolvedBindings.map(b => new BindingData(b, PUBLIC));
|
return Injector.fromResolvedBindings(resolvedBindings);
|
||||||
var proto = new ProtoInjector(null, bd, 0);
|
|
||||||
var inj = new Injector(proto);
|
|
||||||
return inj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -466,48 +477,63 @@ export class Injector {
|
||||||
*
|
*
|
||||||
* @param `bindings` A sparse list of {@link ResolvedBinding}s. See `resolve` for the
|
* @param `bindings` A sparse list of {@link ResolvedBinding}s. See `resolve` for the
|
||||||
* {@link Injector}.
|
* {@link Injector}.
|
||||||
* @param `defaultBindings` Setting to true will auto-create bindings.
|
|
||||||
*/
|
*/
|
||||||
static fromResolvedBindings(bindings: List<ResolvedBinding>,
|
static fromResolvedBindings(bindings: List<ResolvedBinding>): Injector {
|
||||||
{defaultBindings = false}: any = {}): Injector {
|
var bd = bindings.map(b => new BindingWithVisibility(b, PUBLIC));
|
||||||
var bd = bindings.map(b => new BindingData(b, PUBLIC));
|
var proto = new ProtoInjector(bd, 0);
|
||||||
var proto = new ProtoInjector(null, bd, 0);
|
|
||||||
var inj = new Injector(proto);
|
var inj = new Injector(proto);
|
||||||
return inj;
|
return inj;
|
||||||
}
|
}
|
||||||
|
|
||||||
_strategy: InjectorStrategy;
|
_strategy: InjectorStrategy;
|
||||||
_parent: Injector;
|
_isBoundary: boolean = false;
|
||||||
_host: Injector;
|
|
||||||
_constructionCounter: number = 0;
|
_constructionCounter: number = 0;
|
||||||
|
|
||||||
// TODO vsavkin remove it after DI and EI are merged
|
// TODO vsavkin remove it after DI and EI are merged
|
||||||
private _ei: any;
|
ei: any;
|
||||||
|
|
||||||
constructor(public _proto: ProtoInjector) {
|
constructor(public _proto: ProtoInjector, public _parent: Injector = null) {
|
||||||
this._strategy = _proto._strategy.createInjectorStrategy(this);
|
this._strategy = _proto._strategy.createInjectorStrategy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get(token): any { return this._getByKey(Key.get(token), unbounded, false, null); }
|
/**
|
||||||
|
* Retrieves an instance from the injector.
|
||||||
|
*
|
||||||
|
* @param `token`: usually the `Type` of an object. (Same as the token used while setting up a
|
||||||
|
*binding).
|
||||||
|
* @returns an instance represented by the token. Throws if not found.
|
||||||
|
*/
|
||||||
|
get(token): any { return this._getByKey(Key.get(token), unbounded, false, PUBLIC_AND_PRIVATE); }
|
||||||
|
|
||||||
getOptional(token): any { return this._getByKey(Key.get(token), unbounded, true, null); }
|
/**
|
||||||
|
* Retrieves an instance from the injector.
|
||||||
getObjAtIndex(index: number): any { return this._strategy.getObjAtIndex(index); }
|
*
|
||||||
|
* @param `token`: usually a `Type`. (Same as the token used while setting up a binding).
|
||||||
get parent(): Injector { return this._parent; }
|
* @returns an instance represented by the token. Returns `null` if not found.
|
||||||
|
*/
|
||||||
get strategy() { return this._strategy; }
|
getOptional(token): any {
|
||||||
|
return this._getByKey(Key.get(token), unbounded, true, PUBLIC_AND_PRIVATE);
|
||||||
hydrate(parent: Injector, host: Injector, ei: any) {
|
|
||||||
this._constructionCounter = 0;
|
|
||||||
this._parent = parent;
|
|
||||||
this._host = host;
|
|
||||||
this._ei = ei;
|
|
||||||
|
|
||||||
this._strategy.hydrate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dehydrate(): void { this._strategy.dehydrate(); }
|
/**
|
||||||
|
* Retrieves an instance from the injector.
|
||||||
|
*
|
||||||
|
* @param `index`: index of an instance.
|
||||||
|
* @returns an instance represented by the index. Throws if not found.
|
||||||
|
*/
|
||||||
|
getAt(index: number): any { return this._strategy.getObjAtIndex(index); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct parent of this injector.
|
||||||
|
*/
|
||||||
|
get parent(): Injector { return this._parent; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal. Do not use.
|
||||||
|
*
|
||||||
|
* We return `any` not to export the InjectorStrategy type.
|
||||||
|
*/
|
||||||
|
get internalStrategy(): any { return this._strategy; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a child injector and loads a new set of bindings into it.
|
* Creates a child injector and loads a new set of bindings into it.
|
||||||
|
@ -522,11 +548,7 @@ export class Injector {
|
||||||
*/
|
*/
|
||||||
resolveAndCreateChild(bindings: List<Type | Binding | List<any>>): Injector {
|
resolveAndCreateChild(bindings: List<Type | Binding | List<any>>): Injector {
|
||||||
var resovledBindings = Injector.resolve(bindings);
|
var resovledBindings = Injector.resolve(bindings);
|
||||||
var bd = resovledBindings.map(b => new BindingData(b, PUBLIC));
|
return this.createChildFromResolved(resovledBindings);
|
||||||
var proto = new ProtoInjector(this._proto, bd, 1);
|
|
||||||
var inj = new Injector(proto);
|
|
||||||
inj._parent = this;
|
|
||||||
return inj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -537,14 +559,14 @@ export class Injector {
|
||||||
* @returns a new child {@link Injector}.
|
* @returns a new child {@link Injector}.
|
||||||
*/
|
*/
|
||||||
createChildFromResolved(bindings: List<ResolvedBinding>): Injector {
|
createChildFromResolved(bindings: List<ResolvedBinding>): Injector {
|
||||||
var bd = bindings.map(b => new BindingData(b, PUBLIC));
|
var bd = bindings.map(b => new BindingWithVisibility(b, PUBLIC));
|
||||||
var proto = new ProtoInjector(this._proto, bd, 1);
|
var proto = new ProtoInjector(bd, 1);
|
||||||
var inj = new Injector(proto);
|
var inj = new Injector(proto);
|
||||||
inj._parent = this;
|
inj._parent = this;
|
||||||
return inj;
|
return inj;
|
||||||
}
|
}
|
||||||
|
|
||||||
_new(binding: ResolvedBinding): any {
|
_new(binding: ResolvedBinding, visibility: number): any {
|
||||||
if (this._constructionCounter++ > this._strategy.getMaxNumberOfObjects()) {
|
if (this._constructionCounter++ > this._strategy.getMaxNumberOfObjects()) {
|
||||||
throw new CyclicDependencyError(binding.key);
|
throw new CyclicDependencyError(binding.key);
|
||||||
}
|
}
|
||||||
|
@ -555,26 +577,26 @@ export class Injector {
|
||||||
|
|
||||||
var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19;
|
var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19;
|
||||||
try {
|
try {
|
||||||
d0 = length > 0 ? this._getByDependency(deps[0], binding.key) : null;
|
d0 = length > 0 ? this._getByDependency(deps[0], visibility) : null;
|
||||||
d1 = length > 1 ? this._getByDependency(deps[1], binding.key) : null;
|
d1 = length > 1 ? this._getByDependency(deps[1], visibility) : null;
|
||||||
d2 = length > 2 ? this._getByDependency(deps[2], binding.key) : null;
|
d2 = length > 2 ? this._getByDependency(deps[2], visibility) : null;
|
||||||
d3 = length > 3 ? this._getByDependency(deps[3], binding.key) : null;
|
d3 = length > 3 ? this._getByDependency(deps[3], visibility) : null;
|
||||||
d4 = length > 4 ? this._getByDependency(deps[4], binding.key) : null;
|
d4 = length > 4 ? this._getByDependency(deps[4], visibility) : null;
|
||||||
d5 = length > 5 ? this._getByDependency(deps[5], binding.key) : null;
|
d5 = length > 5 ? this._getByDependency(deps[5], visibility) : null;
|
||||||
d6 = length > 6 ? this._getByDependency(deps[6], binding.key) : null;
|
d6 = length > 6 ? this._getByDependency(deps[6], visibility) : null;
|
||||||
d7 = length > 7 ? this._getByDependency(deps[7], binding.key) : null;
|
d7 = length > 7 ? this._getByDependency(deps[7], visibility) : null;
|
||||||
d8 = length > 8 ? this._getByDependency(deps[8], binding.key) : null;
|
d8 = length > 8 ? this._getByDependency(deps[8], visibility) : null;
|
||||||
d9 = length > 9 ? this._getByDependency(deps[9], binding.key) : null;
|
d9 = length > 9 ? this._getByDependency(deps[9], visibility) : null;
|
||||||
d10 = length > 10 ? this._getByDependency(deps[10], binding.key) : null;
|
d10 = length > 10 ? this._getByDependency(deps[10], visibility) : null;
|
||||||
d11 = length > 11 ? this._getByDependency(deps[11], binding.key) : null;
|
d11 = length > 11 ? this._getByDependency(deps[11], visibility) : null;
|
||||||
d12 = length > 12 ? this._getByDependency(deps[12], binding.key) : null;
|
d12 = length > 12 ? this._getByDependency(deps[12], visibility) : null;
|
||||||
d13 = length > 13 ? this._getByDependency(deps[13], binding.key) : null;
|
d13 = length > 13 ? this._getByDependency(deps[13], visibility) : null;
|
||||||
d14 = length > 14 ? this._getByDependency(deps[14], binding.key) : null;
|
d14 = length > 14 ? this._getByDependency(deps[14], visibility) : null;
|
||||||
d15 = length > 15 ? this._getByDependency(deps[15], binding.key) : null;
|
d15 = length > 15 ? this._getByDependency(deps[15], visibility) : null;
|
||||||
d16 = length > 16 ? this._getByDependency(deps[16], binding.key) : null;
|
d16 = length > 16 ? this._getByDependency(deps[16], visibility) : null;
|
||||||
d17 = length > 17 ? this._getByDependency(deps[17], binding.key) : null;
|
d17 = length > 17 ? this._getByDependency(deps[17], visibility) : null;
|
||||||
d18 = length > 18 ? this._getByDependency(deps[18], binding.key) : null;
|
d18 = length > 18 ? this._getByDependency(deps[18], visibility) : null;
|
||||||
d19 = length > 19 ? this._getByDependency(deps[19], binding.key) : null;
|
d19 = length > 19 ? this._getByDependency(deps[19], visibility) : null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof AbstractBindingError) e.addKey(binding.key);
|
if (e instanceof AbstractBindingError) e.addKey(binding.key);
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -656,38 +678,37 @@ export class Injector {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getByDependency(dep: any, requestor: Key): any {
|
private _getByDependency(dep: Dependency, bindingVisibility: number): any {
|
||||||
var special = isPresent(this._ei) ? this._ei.getDependency(dep) : undefinedValue;
|
var special = isPresent(this.ei) ? this.ei.getDependency(dep) : undefinedValue;
|
||||||
if (special !== undefinedValue) {
|
if (special !== undefinedValue) {
|
||||||
return special;
|
return special;
|
||||||
} else {
|
} else {
|
||||||
return this._getByKey(dep.key, dep.visibility, dep.optional, requestor);
|
return this._getByKey(dep.key, dep.visibility, dep.optional, bindingVisibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getByKey(key: Key, depVisibility: any, optional: boolean, requestor: Key): any {
|
private _getByKey(key: Key, depVisibility: Visibility, optional: boolean,
|
||||||
|
bindingVisibility: number): any {
|
||||||
if (key.token === Injector) {
|
if (key.token === Injector) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inj = this;
|
var inj = this;
|
||||||
var ei = this._ei;
|
var lastInjector = false;
|
||||||
|
|
||||||
// TODO vsavkin remove after DI and EI are merged
|
|
||||||
var bindingVisibility =
|
|
||||||
isPresent(ei) && ei.isComponentKey(requestor) ? PUBLIC_AND_PRIVATE : PUBLIC;
|
|
||||||
|
|
||||||
var depth = depVisibility.depth;
|
var depth = depVisibility.depth;
|
||||||
|
|
||||||
if (!depVisibility.includeSelf) {
|
if (!depVisibility.includeSelf) {
|
||||||
depth -= inj._proto.distanceToParent;
|
depth -= inj._proto.distanceToParent;
|
||||||
|
|
||||||
if (isPresent(inj._parent)) {
|
if (inj._isBoundary) {
|
||||||
inj = inj._parent;
|
if (depVisibility.crossBoundaries) {
|
||||||
} else {
|
bindingVisibility = PUBLIC_AND_PRIVATE;
|
||||||
inj = inj._host;
|
} else {
|
||||||
bindingVisibility = depVisibility.crossComponentBoundaries ? PUBLIC : PRIVATE;
|
bindingVisibility = PRIVATE;
|
||||||
|
lastInjector = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
inj = inj._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (inj != null && depth >= 0) {
|
while (inj != null && depth >= 0) {
|
||||||
|
@ -696,25 +717,17 @@ export class Injector {
|
||||||
|
|
||||||
depth -= inj._proto.distanceToParent;
|
depth -= inj._proto.distanceToParent;
|
||||||
|
|
||||||
// we check only one mode with the PRIVATE visibility
|
if (lastInjector) break;
|
||||||
if (bindingVisibility === PRIVATE) break;
|
|
||||||
|
|
||||||
if (isPresent(inj._parent)) {
|
if (inj._isBoundary) {
|
||||||
inj = inj._parent;
|
if (depVisibility.crossBoundaries) {
|
||||||
} else {
|
bindingVisibility = PUBLIC_AND_PRIVATE;
|
||||||
inj = inj._host;
|
} else {
|
||||||
bindingVisibility = depVisibility.crossComponentBoundaries ? PUBLIC : PRIVATE;
|
bindingVisibility = PRIVATE;
|
||||||
}
|
lastInjector = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO vsavkin remove after DI and EI are merged
|
|
||||||
if (isPresent(ei)) {
|
|
||||||
var appInj = <Injector>this._ei.appInjector(requestor);
|
|
||||||
if (optional) {
|
|
||||||
return appInj.getOptional(key);
|
|
||||||
} else {
|
|
||||||
return appInj.get(key);
|
|
||||||
}
|
}
|
||||||
|
inj = inj._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optional) {
|
if (optional) {
|
||||||
|
@ -723,12 +736,6 @@ export class Injector {
|
||||||
throw new NoBindingError(key);
|
throw new NoBindingError(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO vsavkin remove after DI and EI are merged
|
|
||||||
getAppInjector(): Injector {
|
|
||||||
if (isBlank(this._ei)) return this;
|
|
||||||
return <Injector>this._ei.appInjector(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import * as modelModule from './model';
|
||||||
*
|
*
|
||||||
* @Component({
|
* @Component({
|
||||||
* selector: 'login-comp',
|
* selector: 'login-comp',
|
||||||
* appInjector: [
|
* viewInjector: [
|
||||||
* FormBuilder
|
* FormBuilder
|
||||||
* ]
|
* ]
|
||||||
* })
|
* })
|
||||||
|
|
|
@ -66,7 +66,7 @@ export class XHRConnection implements Connection {
|
||||||
* ```
|
* ```
|
||||||
* import {Http, MyNodeBackend, httpInjectables, BaseRequestOptions} from 'angular2/http';
|
* import {Http, MyNodeBackend, httpInjectables, BaseRequestOptions} from 'angular2/http';
|
||||||
* @Component({
|
* @Component({
|
||||||
* appInjector: [
|
* viewInjector: [
|
||||||
* httpInjectables,
|
* httpInjectables,
|
||||||
* bind(Http).toFactory((backend, options) => {
|
* bind(Http).toFactory((backend, options) => {
|
||||||
* return new Http(backend, options);
|
* return new Http(backend, options);
|
||||||
|
|
|
@ -52,7 +52,7 @@ function mergeOptions(defaultOpts, providedOpts, method, url): RequestOptions {
|
||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
* import {Http, httpInjectables} from 'angular2/http';
|
* import {Http, httpInjectables} from 'angular2/http';
|
||||||
* @Component({selector: 'http-app', appInjector: [httpInjectables]})
|
* @Component({selector: 'http-app', viewInjector: [httpInjectables]})
|
||||||
* @View({templateUrl: 'people.html'})
|
* @View({templateUrl: 'people.html'})
|
||||||
* class PeopleComponent {
|
* class PeopleComponent {
|
||||||
* constructor(http: Http) {
|
* constructor(http: Http) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {Directive, Attribute} from 'angular2/src/core/annotations/decorators';
|
import {Directive, Attribute} from 'angular2/src/core/annotations/decorators';
|
||||||
import {DynamicComponentLoader, ComponentRef, ElementRef} from 'angular2/core';
|
import {DynamicComponentLoader, ComponentRef, ElementRef} from 'angular2/core';
|
||||||
import {Injector, bind} from 'angular2/di';
|
import {Injector, bind, Dependency, undefinedValue} from 'angular2/di';
|
||||||
|
|
||||||
import * as routerMod from './router';
|
import * as routerMod from './router';
|
||||||
import {Instruction, RouteParams} from './instruction'
|
import {Instruction, RouteParams} from './instruction'
|
||||||
|
@ -24,20 +24,14 @@ import {Instruction, RouteParams} from './instruction'
|
||||||
export class RouterOutlet {
|
export class RouterOutlet {
|
||||||
private _childRouter: routerMod.Router = null;
|
private _childRouter: routerMod.Router = null;
|
||||||
private _componentRef: ComponentRef = null;
|
private _componentRef: ComponentRef = null;
|
||||||
private _elementRef: ElementRef;
|
|
||||||
private _currentInstruction: Instruction = null;
|
private _currentInstruction: Instruction = null;
|
||||||
private _injector: Injector;
|
|
||||||
|
|
||||||
constructor(elementRef: ElementRef, private _loader: DynamicComponentLoader,
|
constructor(private _elementRef: ElementRef, private _loader: DynamicComponentLoader,
|
||||||
private _parentRouter: routerMod.Router, _injector: Injector,
|
private _parentRouter: routerMod.Router, @Attribute('name') nameAttr: string) {
|
||||||
@Attribute('name') nameAttr: string) {
|
|
||||||
// TODO: reintroduce with new // sibling routes
|
// TODO: reintroduce with new // sibling routes
|
||||||
// if (isBlank(nameAttr)) {
|
// if (isBlank(nameAttr)) {
|
||||||
// nameAttr = 'default';
|
// nameAttr = 'default';
|
||||||
//}
|
//}
|
||||||
|
|
||||||
this._injector = _injector.getAppInjector();
|
|
||||||
this._elementRef = elementRef;
|
|
||||||
this._parentRouter.registerOutlet(this);
|
this._parentRouter.registerOutlet(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,15 +49,13 @@ export class RouterOutlet {
|
||||||
|
|
||||||
this._currentInstruction = instruction;
|
this._currentInstruction = instruction;
|
||||||
this._childRouter = this._parentRouter.childRouter(instruction.component);
|
this._childRouter = this._parentRouter.childRouter(instruction.component);
|
||||||
var outletInjector = this._injector.resolveAndCreateChild([
|
var params = new RouteParams(instruction.params());
|
||||||
bind(RouteParams)
|
var bindings = Injector.resolve(
|
||||||
.toValue(new RouteParams(instruction.params())),
|
[bind(RouteParams).toValue(params), bind(routerMod.Router).toValue(this._childRouter)]);
|
||||||
bind(routerMod.Router).toValue(this._childRouter)
|
|
||||||
]);
|
|
||||||
|
|
||||||
return this.deactivate()
|
return this.deactivate()
|
||||||
.then((_) => this._loader.loadNextToLocation(instruction.component, this._elementRef,
|
.then((_) => this._loader.loadNextToLocation(instruction.component, this._elementRef,
|
||||||
outletInjector))
|
bindings))
|
||||||
.then((componentRef) => {
|
.then((componentRef) => {
|
||||||
this._componentRef = componentRef;
|
this._componentRef = componentRef;
|
||||||
return this._childRouter.commit(instruction.child);
|
return this._childRouter.commit(instruction.child);
|
||||||
|
|
|
@ -266,7 +266,7 @@ class DynamicallyCreatedComponentService {}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hello-cmp',
|
selector: 'hello-cmp',
|
||||||
appInjector: [DynamicallyCreatedComponentService],
|
viewInjector: [DynamicallyCreatedComponentService],
|
||||||
lifecycle: [onDestroy]
|
lifecycle: [onDestroy]
|
||||||
})
|
})
|
||||||
@View({template: "{{greeting}}"})
|
@View({template: "{{greeting}}"})
|
||||||
|
|
|
@ -242,8 +242,7 @@ class TestNode extends TreeNode<TestNode> {
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
var defaultPreBuiltObjects = new PreBuiltObjects(null, <any>new DummyView(1), null);
|
var defaultPreBuiltObjects = new PreBuiltObjects(null, <any>new DummyView(1), null);
|
||||||
var appInjector = Injector.resolveAndCreate([]);
|
|
||||||
|
|
||||||
// An injector with more than 10 bindings will switch to the dynamic strategy
|
// An injector with more than 10 bindings will switch to the dynamic strategy
|
||||||
var dynamicBindings = [];
|
var dynamicBindings = [];
|
||||||
|
|
||||||
|
@ -269,48 +268,41 @@ export function main() {
|
||||||
return [lookupName(tree), children];
|
return [lookupName(tree), children];
|
||||||
}
|
}
|
||||||
|
|
||||||
function injector(bindings, lightDomAppInjector = null, isComponent: boolean = false,
|
function injector(bindings, imperativelyCreatedInjector = null, isComponent: boolean = false,
|
||||||
preBuiltObjects = null, attributes = null, dirVariableBindings = null) {
|
preBuiltObjects = null, attributes = null, dirVariableBindings = null) {
|
||||||
if (isBlank(lightDomAppInjector)) lightDomAppInjector = appInjector;
|
|
||||||
|
|
||||||
var proto = createPei(null, 0, bindings, 0, isComponent, dirVariableBindings);
|
var proto = createPei(null, 0, bindings, 0, isComponent, dirVariableBindings);
|
||||||
proto.attributes = attributes;
|
proto.attributes = attributes;
|
||||||
|
|
||||||
var inj = proto.instantiate(null);
|
var inj = proto.instantiate(null);
|
||||||
var preBuilt = isPresent(preBuiltObjects) ? preBuiltObjects : defaultPreBuiltObjects;
|
var preBuilt = isPresent(preBuiltObjects) ? preBuiltObjects : defaultPreBuiltObjects;
|
||||||
inj.hydrate(lightDomAppInjector, null, preBuilt);
|
inj.hydrate(imperativelyCreatedInjector, null, preBuilt);
|
||||||
return inj;
|
return inj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parentChildInjectors(parentBindings, childBindings, parentPreBuildObjects = null) {
|
function parentChildInjectors(parentBindings, childBindings, parentPreBuildObjects = null) {
|
||||||
if (isBlank(parentPreBuildObjects)) parentPreBuildObjects = defaultPreBuiltObjects;
|
if (isBlank(parentPreBuildObjects)) parentPreBuildObjects = defaultPreBuiltObjects;
|
||||||
|
|
||||||
var inj = Injector.resolveAndCreate([]);
|
|
||||||
|
|
||||||
|
|
||||||
var protoParent = createPei(null, 0, parentBindings);
|
var protoParent = createPei(null, 0, parentBindings);
|
||||||
var parent = protoParent.instantiate(null);
|
var parent = protoParent.instantiate(null);
|
||||||
|
|
||||||
parent.hydrate(inj, null, parentPreBuildObjects);
|
parent.hydrate(null, null, parentPreBuildObjects);
|
||||||
|
|
||||||
var protoChild = createPei(protoParent, 1, childBindings, 1, false);
|
var protoChild = createPei(protoParent, 1, childBindings, 1, false);
|
||||||
var child = protoChild.instantiate(parent);
|
var child = protoChild.instantiate(parent);
|
||||||
child.hydrate(inj, null, defaultPreBuiltObjects);
|
child.hydrate(null, null, defaultPreBuiltObjects);
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hostShadowInjectors(hostBindings: List<any>,
|
function hostShadowInjectors(hostBindings: List<any>,
|
||||||
shadowBindings: List<any>): ElementInjector {
|
shadowBindings: List<any>): ElementInjector {
|
||||||
var inj = Injector.resolveAndCreate([]);
|
|
||||||
|
|
||||||
var protoHost = createPei(null, 0, hostBindings, 0, true);
|
var protoHost = createPei(null, 0, hostBindings, 0, true);
|
||||||
var host = protoHost.instantiate(null);
|
var host = protoHost.instantiate(null);
|
||||||
host.hydrate(inj, null, defaultPreBuiltObjects);
|
host.hydrate(null, null, defaultPreBuiltObjects);
|
||||||
|
|
||||||
var protoShadow = createPei(null, 0, shadowBindings, 0, false);
|
var protoShadow = createPei(null, 0, shadowBindings, 0, false);
|
||||||
var shadow = protoShadow.instantiate(null);
|
var shadow = protoShadow.instantiate(null);
|
||||||
shadow.hydrate(host.getShadowDomAppInjector(), host, null);
|
shadow.hydrate(null, host, null);
|
||||||
|
|
||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
|
@ -570,6 +562,7 @@ export function main() {
|
||||||
|
|
||||||
var extraBindings = context['bindings'];
|
var extraBindings = context['bindings'];
|
||||||
describe(`${context['strategy']} strategy`, () => {
|
describe(`${context['strategy']} strategy`, () => {
|
||||||
|
|
||||||
describe("hydrate", () => {
|
describe("hydrate", () => {
|
||||||
it("should instantiate directives that have no dependencies", () => {
|
it("should instantiate directives that have no dependencies", () => {
|
||||||
var bindings = ListWrapper.concat([SimpleDirective], extraBindings);
|
var bindings = ListWrapper.concat([SimpleDirective], extraBindings);
|
||||||
|
@ -609,22 +602,42 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should instantiate hostInjector injectables that have dependencies", () => {
|
it("should instantiate hostInjector injectables that have dependencies", () => {
|
||||||
var inj = injector(ListWrapper.concat(
|
var hostInjector = [
|
||||||
[DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Directive({
|
|
||||||
hostInjector: [
|
|
||||||
bind('injectable1')
|
bind('injectable1')
|
||||||
.toValue('injectable1'),
|
.toValue('injectable1'),
|
||||||
bind('injectable2')
|
bind('injectable2')
|
||||||
.toFactory(
|
.toFactory(
|
||||||
(val) => `${val}-injectable2`,
|
(val) => `${val}-injectable2`,
|
||||||
['injectable1'])
|
['injectable1'])
|
||||||
]
|
];
|
||||||
}))],
|
|
||||||
|
var inj = injector(ListWrapper.concat(
|
||||||
|
[DirectiveBinding.createFromType(SimpleDirective,
|
||||||
|
new dirAnn.Directive({hostInjector: hostInjector}))],
|
||||||
extraBindings));
|
extraBindings));
|
||||||
|
|
||||||
expect(inj.get('injectable2')).toEqual('injectable1-injectable2');
|
expect(inj.get('injectable2')).toEqual('injectable1-injectable2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should instantiate components that depends on viewInjector dependencies", () => {
|
it("should instantiate viewInjector injectables that have dependencies", () => {
|
||||||
|
var viewInjector = [
|
||||||
|
bind('injectable1')
|
||||||
|
.toValue('injectable1'),
|
||||||
|
bind('injectable2')
|
||||||
|
.toFactory(
|
||||||
|
(val) => `${val}-injectable2`,
|
||||||
|
['injectable1'])
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
var inj = injector(ListWrapper.concat(
|
||||||
|
[DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component({
|
||||||
|
viewInjector: viewInjector}))], extraBindings),
|
||||||
|
null, true);
|
||||||
|
expect(inj.get('injectable2')).toEqual('injectable1-injectable2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should instantiate components that depend on viewInjector bindings", () => {
|
||||||
var inj = injector(
|
var inj = injector(
|
||||||
ListWrapper.concat([DirectiveBinding.createFromType(NeedsService, new dirAnn.Component({
|
ListWrapper.concat([DirectiveBinding.createFromType(NeedsService, new dirAnn.Component({
|
||||||
viewInjector: [bind('service').toValue('service')]
|
viewInjector: [bind('service').toValue('service')]
|
||||||
|
@ -634,16 +647,19 @@ export function main() {
|
||||||
expect(inj.get(NeedsService).service).toEqual('service');
|
expect(inj.get(NeedsService).service).toEqual('service');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should prioritize viewInjector over hostInjector for the same binding", () => {
|
it("should not instantiate other directives that depend on viewInjector bindings",
|
||||||
var inj = injector(
|
() => {
|
||||||
ListWrapper.concat([DirectiveBinding.createFromType(NeedsService, new dirAnn.Component({
|
var directiveAnnotation = new dirAnn.Component({
|
||||||
hostInjector: [bind('service').toValue('hostService')],
|
viewInjector: ListWrapper.concat([bind("service").toValue("service")], extraBindings)
|
||||||
viewInjector: [bind('service').toValue('viewService')]})
|
});
|
||||||
)], extraBindings), null, true);
|
var componentDirective =
|
||||||
expect(inj.get(NeedsService).service).toEqual('viewService');
|
DirectiveBinding.createFromType(SimpleDirective, directiveAnnotation);
|
||||||
});
|
expect(() => { injector([componentDirective, NeedsService], null); })
|
||||||
|
.toThrowError(containsRegexp(
|
||||||
it("should instantiate a directive in a view that depends on hostInjector bindings of the component", () => {
|
`No provider for service! (${stringify(NeedsService) } -> service)`));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should instantiate directives that depend on hostInjector bindings of other directives", () => {
|
||||||
var shadowInj = hostShadowInjectors(
|
var shadowInj = hostShadowInjectors(
|
||||||
ListWrapper.concat([DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component({
|
ListWrapper.concat([DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component({
|
||||||
hostInjector: [bind('service').toValue('hostService')]})
|
hostInjector: [bind('service').toValue('hostService')]})
|
||||||
|
@ -652,6 +668,23 @@ export function main() {
|
||||||
);
|
);
|
||||||
expect(shadowInj.get(NeedsService).service).toEqual('hostService');
|
expect(shadowInj.get(NeedsService).service).toEqual('hostService');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should instantiate directives that depend on imperativley created injector bindings", () => {
|
||||||
|
var imperativelyCreatedInjector = Injector.resolveAndCreate([
|
||||||
|
bind("service").toValue('appService')
|
||||||
|
]);
|
||||||
|
var inj = injector([NeedsService], imperativelyCreatedInjector);
|
||||||
|
expect(inj.get(NeedsService).service).toEqual('appService');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should prioritize viewInjector over hostInjector for the same binding", () => {
|
||||||
|
var inj = injector(
|
||||||
|
ListWrapper.concat([DirectiveBinding.createFromType(NeedsService, new dirAnn.Component({
|
||||||
|
hostInjector: [bind('service').toValue('hostService')],
|
||||||
|
viewInjector: [bind('service').toValue('viewService')]})
|
||||||
|
)], extraBindings), null, true);
|
||||||
|
expect(inj.get(NeedsService).service).toEqual('viewService');
|
||||||
|
});
|
||||||
|
|
||||||
it("should not instantiate a directive in a view that has an ancestor dependency on hostInjector"+
|
it("should not instantiate a directive in a view that has an ancestor dependency on hostInjector"+
|
||||||
" bindings of a decorator directive", () => {
|
" bindings of a decorator directive", () => {
|
||||||
|
@ -668,16 +701,6 @@ export function main() {
|
||||||
}).toThrowError(new RegExp("No provider for service!"));
|
}).toThrowError(new RegExp("No provider for service!"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should instantiate directives that depend on app services", () => {
|
|
||||||
var appInjector = Injector.resolveAndCreate(
|
|
||||||
ListWrapper.concat([bind("service").toValue("service")], extraBindings));
|
|
||||||
var inj = injector([NeedsService], appInjector);
|
|
||||||
|
|
||||||
var d = inj.get(NeedsService);
|
|
||||||
expect(d).toBeAnInstanceOf(NeedsService);
|
|
||||||
expect(d.service).toEqual("service");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should instantiate directives that depend on pre built objects", () => {
|
it("should instantiate directives that depend on pre built objects", () => {
|
||||||
var protoView = new AppProtoView(null, null, null, null);
|
var protoView = new AppProtoView(null, null, null, null);
|
||||||
var bindings = ListWrapper.concat([NeedsProtoViewRef], extraBindings);
|
var bindings = ListWrapper.concat([NeedsProtoViewRef], extraBindings);
|
||||||
|
@ -686,14 +709,6 @@ export function main() {
|
||||||
expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
|
expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return app services", () => {
|
|
||||||
var appInjector = Injector.resolveAndCreate(
|
|
||||||
ListWrapper.concat([bind("service").toValue("service")], extraBindings));
|
|
||||||
var inj = injector([], appInjector);
|
|
||||||
|
|
||||||
expect(inj.get('service')).toEqual('service');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should get directives from parent", () => {
|
it("should get directives from parent", () => {
|
||||||
var child = parentChildInjectors(ListWrapper.concat([SimpleDirective], extraBindings),
|
var child = parentChildInjectors(ListWrapper.concat([SimpleDirective], extraBindings),
|
||||||
[NeedsDirectiveFromParent]);
|
[NeedsDirectiveFromParent]);
|
||||||
|
@ -752,7 +767,7 @@ export function main() {
|
||||||
expect(d.dependency).toEqual(null);
|
expect(d.dependency).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should accept bindings instead types", () => {
|
it("should accept bindings instead of types", () => {
|
||||||
var inj = injector(
|
var inj = injector(
|
||||||
ListWrapper.concat([bind(SimpleDirective).toClass(SimpleDirective)], extraBindings));
|
ListWrapper.concat([bind(SimpleDirective).toClass(SimpleDirective)], extraBindings));
|
||||||
expect(inj.get(SimpleDirective)).toBeAnInstanceOf(SimpleDirective);
|
expect(inj.get(SimpleDirective)).toBeAnInstanceOf(SimpleDirective);
|
||||||
|
@ -772,8 +787,6 @@ export function main() {
|
||||||
.toThrowError(`Index ${firsIndexOut} is out-of-bounds.`);
|
.toThrowError(`Index ${firsIndexOut} is out-of-bounds.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe("shadow DOM components", () => {
|
|
||||||
it("should instantiate directives that depend on the containing component", () => {
|
it("should instantiate directives that depend on the containing component", () => {
|
||||||
var directiveBinding =
|
var directiveBinding =
|
||||||
DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component());
|
DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component());
|
||||||
|
@ -798,33 +811,6 @@ export function main() {
|
||||||
.toThrowError(containsRegexp(
|
.toThrowError(containsRegexp(
|
||||||
`No provider for ${stringify(SimpleDirective) }! (${stringify(NeedsDirective) } -> ${stringify(SimpleDirective) })`));
|
`No provider for ${stringify(SimpleDirective) }! (${stringify(NeedsDirective) } -> ${stringify(SimpleDirective) })`));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should instantiate component directives that depend on app services in the shadow app injector",
|
|
||||||
() => {
|
|
||||||
var directiveAnnotation = new dirAnn.Component({
|
|
||||||
appInjector: ListWrapper.concat([bind("service").toValue("service")], extraBindings)
|
|
||||||
});
|
|
||||||
var componentDirective =
|
|
||||||
DirectiveBinding.createFromType(NeedsService, directiveAnnotation);
|
|
||||||
var inj = injector([componentDirective], null, true);
|
|
||||||
|
|
||||||
var d = inj.get(NeedsService);
|
|
||||||
expect(d).toBeAnInstanceOf(NeedsService);
|
|
||||||
expect(d.service).toEqual("service");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not instantiate other directives that depend on app services in the shadow app injector",
|
|
||||||
() => {
|
|
||||||
var directiveAnnotation = new dirAnn.Component({
|
|
||||||
appInjector: ListWrapper.concat([bind("service").toValue("service")], extraBindings)
|
|
||||||
});
|
|
||||||
var componentDirective =
|
|
||||||
DirectiveBinding.createFromType(SimpleDirective, directiveAnnotation);
|
|
||||||
expect(() => { injector([componentDirective, NeedsService], null); })
|
|
||||||
.toThrowError(containsRegexp(
|
|
||||||
`No provider for service! (${stringify(NeedsService) } -> service)`));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("lifecycle", () => {
|
describe("lifecycle", () => {
|
||||||
|
@ -1058,8 +1044,8 @@ export function main() {
|
||||||
|
|
||||||
var parent = protoParent.instantiate(null);
|
var parent = protoParent.instantiate(null);
|
||||||
var child = protoChild.instantiate(parent);
|
var child = protoChild.instantiate(parent);
|
||||||
parent.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
parent.hydrate(null, null, preBuildObjects);
|
||||||
child.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
child.hydrate(null, null, preBuildObjects);
|
||||||
|
|
||||||
expectDirectives(parent.get(NeedsQuery).query, CountingDirective, [0, 1]);
|
expectDirectives(parent.get(NeedsQuery).query, CountingDirective, [0, 1]);
|
||||||
});
|
});
|
||||||
|
@ -1071,8 +1057,8 @@ export function main() {
|
||||||
|
|
||||||
var parent = protoParent.instantiate(null);
|
var parent = protoParent.instantiate(null);
|
||||||
var child = protoChild.instantiate(parent);
|
var child = protoChild.instantiate(parent);
|
||||||
parent.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
parent.hydrate(null, null, preBuildObjects);
|
||||||
child.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
child.hydrate(null, null, preBuildObjects);
|
||||||
|
|
||||||
child.unlink();
|
child.unlink();
|
||||||
|
|
||||||
|
@ -1089,9 +1075,9 @@ export function main() {
|
||||||
var child1 = protoChild1.instantiate(parent);
|
var child1 = protoChild1.instantiate(parent);
|
||||||
var child2 = protoChild2.instantiate(parent);
|
var child2 = protoChild2.instantiate(parent);
|
||||||
|
|
||||||
parent.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
parent.hydrate(null, null, preBuildObjects);
|
||||||
child1.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
child1.hydrate(null, null, preBuildObjects);
|
||||||
child2.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
child2.hydrate(null, null, preBuildObjects);
|
||||||
|
|
||||||
child1.unlink();
|
child1.unlink();
|
||||||
child1.link(parent);
|
child1.link(parent);
|
||||||
|
@ -1110,9 +1096,9 @@ export function main() {
|
||||||
var child1 = protoChild1.instantiate(parent);
|
var child1 = protoChild1.instantiate(parent);
|
||||||
var child2 = protoChild2.instantiate(parent);
|
var child2 = protoChild2.instantiate(parent);
|
||||||
|
|
||||||
parent.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
parent.hydrate(null, null, preBuildObjects);
|
||||||
child1.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
child1.hydrate(null, null, preBuildObjects);
|
||||||
child2.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
child2.hydrate(null, null, preBuildObjects);
|
||||||
|
|
||||||
child2.unlink();
|
child2.unlink();
|
||||||
child2.linkAfter(parent, null);
|
child2.linkAfter(parent, null);
|
||||||
|
@ -1131,9 +1117,9 @@ export function main() {
|
||||||
var parent = protoParent.instantiate(grandParent);
|
var parent = protoParent.instantiate(grandParent);
|
||||||
var child = protoChild.instantiate(parent);
|
var child = protoChild.instantiate(parent);
|
||||||
|
|
||||||
grandParent.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
grandParent.hydrate(null, null, preBuildObjects);
|
||||||
parent.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
parent.hydrate(null, null, preBuildObjects);
|
||||||
child.hydrate(Injector.resolveAndCreate([]), null, preBuildObjects);
|
child.hydrate(null, null, preBuildObjects);
|
||||||
|
|
||||||
var queryList1 = grandParent.get(NeedsQuery).query;
|
var queryList1 = grandParent.get(NeedsQuery).query;
|
||||||
var queryList2 = parent.get(NeedsQuery).query;
|
var queryList2 = parent.get(NeedsQuery).query;
|
||||||
|
|
|
@ -38,7 +38,7 @@ void functionThatThrowsNonError() {
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
describe('TypeLiteral', () {
|
describe('TypeLiteral', () {
|
||||||
it('should publish via appInjector', inject([
|
it('should publish via viewInjector', inject([
|
||||||
TestComponentBuilder,
|
TestComponentBuilder,
|
||||||
AsyncTestCompleter
|
AsyncTestCompleter
|
||||||
], (tb, async) {
|
], (tb, async) {
|
||||||
|
@ -143,7 +143,7 @@ class Dummy {}
|
||||||
|
|
||||||
@Component(
|
@Component(
|
||||||
selector: 'type-literal-component',
|
selector: 'type-literal-component',
|
||||||
appInjector: const [
|
viewInjector: const [
|
||||||
const Binding(const TypeLiteral<List<String>>(),
|
const Binding(const TypeLiteral<List<String>>(),
|
||||||
toValue: const <String>['Hello', 'World'])
|
toValue: const <String>['Hello', 'World'])
|
||||||
])
|
])
|
||||||
|
|
|
@ -1319,18 +1319,17 @@ class SimpleImperativeViewComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Directive({selector: 'dynamic-vp'})
|
@Directive({selector: 'dynamic-vp'})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class DynamicViewport {
|
class DynamicViewport {
|
||||||
done;
|
done;
|
||||||
constructor(vc: ViewContainerRef, inj: Injector, compiler: Compiler) {
|
constructor(vc: ViewContainerRef, compiler: Compiler) {
|
||||||
var myService = new MyService();
|
var myService = new MyService();
|
||||||
myService.greeting = 'dynamic greet';
|
myService.greeting = 'dynamic greet';
|
||||||
|
|
||||||
|
var bindings = Injector.resolve([bind(MyService).toValue(myService)]);
|
||||||
this.done = compiler.compileInHost(ChildCompUsingService)
|
this.done = compiler.compileInHost(ChildCompUsingService)
|
||||||
.then((hostPv) => {vc.create(hostPv, 0, null,
|
.then((hostPv) => {vc.create(hostPv, 0, null, bindings)});
|
||||||
inj.createChildFromResolved(Injector.resolve(
|
|
||||||
[bind(MyService).toValue(myService)])))});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1398,7 +1397,7 @@ class ComponentWithPipes {
|
||||||
prop: string;
|
prop: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'child-cmp', properties: ['dirProp'], appInjector: [MyService]})
|
@Component({selector: 'child-cmp', properties: ['dirProp'], viewInjector: [MyService]})
|
||||||
@View({directives: [MyDir], template: '{{ctxProp}}'})
|
@View({directives: [MyDir], template: '{{ctxProp}}'})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class ChildComp {
|
class ChildComp {
|
||||||
|
@ -1448,7 +1447,7 @@ class CompWithAncestor {
|
||||||
constructor(@Ancestor() someComp: SomeDirective) { this.myAncestor = someComp; }
|
constructor(@Ancestor() someComp: SomeDirective) { this.myAncestor = someComp; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: '[child-cmp2]', appInjector: [MyService]})
|
@Component({selector: '[child-cmp2]', viewInjector: [MyService]})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class ChildComp2 {
|
class ChildComp2 {
|
||||||
ctxProp: string;
|
ctxProp: string;
|
||||||
|
|
|
@ -156,7 +156,7 @@ export function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function directiveBinding({metadata}: {metadata?: any} = {}) {
|
function directiveBinding({metadata}: {metadata?: any} = {}) {
|
||||||
return new DirectiveBinding(Key.get("dummy"), null, [], [], [], [], metadata);
|
return new DirectiveBinding(Key.get("dummy"), null, [], [], [], metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRenderProtoView(elementBinders = null, type: renderApi.ViewType = null) {
|
function createRenderProtoView(elementBinders = null, type: renderApi.ViewType = null) {
|
||||||
|
|
|
@ -301,13 +301,12 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hydrate the view', () => {
|
it('should hydrate the view', () => {
|
||||||
var injector = Injector.resolveAndCreate([]);
|
|
||||||
var contextView =
|
var contextView =
|
||||||
createView(createProtoView([createEmptyElBinder(), createEmptyElBinder()]));
|
createView(createProtoView([createEmptyElBinder(), createEmptyElBinder()]));
|
||||||
manager.createViewInContainer(elementRef(parentView, 0), 0, wrapPv(childProtoView),
|
manager.createViewInContainer(elementRef(parentView, 0), 0, wrapPv(childProtoView),
|
||||||
elementRef(contextView, 1), injector);
|
elementRef(contextView, 1), []);
|
||||||
expect(utils.spy('hydrateViewInContainer'))
|
expect(utils.spy('hydrateViewInContainer'))
|
||||||
.toHaveBeenCalledWith(parentView, 0, contextView, 1, 0, injector);
|
.toHaveBeenCalledWith(parentView, 0, contextView, 1, 0, []);
|
||||||
expect(renderer.spy('hydrateView')).toHaveBeenCalledWith(createdViews[0].render);
|
expect(renderer.spy('hydrateView')).toHaveBeenCalledWith(createdViews[0].render);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,6 @@ export function main() {
|
||||||
|
|
||||||
function createElementInjector(parent = null) {
|
function createElementInjector(parent = null) {
|
||||||
var host = new SpyElementInjector();
|
var host = new SpyElementInjector();
|
||||||
var appInjector = new SpyInjector();
|
|
||||||
var elementInjector =
|
var elementInjector =
|
||||||
isPresent(parent) ? new SpyElementInjectorWithParent(parent) : new SpyElementInjector();
|
isPresent(parent) ? new SpyElementInjectorWithParent(parent) : new SpyElementInjector();
|
||||||
return SpyObject.stub(elementInjector,
|
return SpyObject.stub(elementInjector,
|
||||||
|
@ -79,8 +78,7 @@ export function main() {
|
||||||
'getEventEmitterAccessors': [],
|
'getEventEmitterAccessors': [],
|
||||||
'getHostActionAccessors': [],
|
'getHostActionAccessors': [],
|
||||||
'getComponent': null,
|
'getComponent': null,
|
||||||
'getHost': host,
|
'getHost': host
|
||||||
'getShadowDomAppInjector': appInjector
|
|
||||||
},
|
},
|
||||||
{});
|
{});
|
||||||
}
|
}
|
||||||
|
@ -245,17 +243,6 @@ export function main() {
|
||||||
.toHaveBeenCalledWith(null, contextView.elementInjectors[0].getHost(),
|
.toHaveBeenCalledWith(null, contextView.elementInjectors[0].getHost(),
|
||||||
childView.preBuiltObjects[0]);
|
childView.preBuiltObjects[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the shadowDomAppInjector of the context elementInjector if there is no host',
|
|
||||||
() => {
|
|
||||||
createViews();
|
|
||||||
parentView.elementInjectors[0].spy('getHost').andReturn(null);
|
|
||||||
utils.hydrateViewInContainer(parentView, 0, parentView, 0, 0, null);
|
|
||||||
expect(childView.rootElementInjectors[0].spy('hydrate'))
|
|
||||||
.toHaveBeenCalledWith(parentView.elementInjectors[0].getShadowDomAppInjector(), null,
|
|
||||||
childView.preBuiltObjects[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hydrateRootHostView', () => {
|
describe('hydrateRootHostView', () => {
|
||||||
|
|
|
@ -29,7 +29,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'app', appInjector: [forwardRef(() => Frame)]})
|
@Component({selector: 'app', viewInjector: [forwardRef(() => Frame)]})
|
||||||
@View({
|
@View({
|
||||||
template: `<door><lock></lock></door>`,
|
template: `<door><lock></lock></door>`,
|
||||||
directives: [
|
directives: [
|
||||||
|
|
|
@ -66,7 +66,7 @@ class ChildComp {
|
||||||
constructor() { this.childBinding = 'Original'; }
|
constructor() { this.childBinding = 'Original'; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'parent-comp', appInjector: [Logger]})
|
@Component({selector: 'parent-comp', viewInjector: [Logger]})
|
||||||
@View({
|
@View({
|
||||||
template: `<div class="parent" message="parent">
|
template: `<div class="parent" message="parent">
|
||||||
<span class="parentnested" message="nestedparent">Parent</span>
|
<span class="parentnested" message="nestedparent">Parent</span>
|
||||||
|
@ -110,7 +110,7 @@ class EventsComp {
|
||||||
handleCustom() { this.customed = true; }
|
handleCustom() { this.customed = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'using-for', appInjector: [Logger]})
|
@Component({selector: 'using-for', viewInjector: [Logger]})
|
||||||
@View({
|
@View({
|
||||||
template: `<span *ng-for="#thing of stuff">{{thing}}</span>
|
template: `<span *ng-for="#thing of stuff">{{thing}}</span>
|
||||||
<ul message="list">
|
<ul message="list">
|
||||||
|
|
|
@ -14,7 +14,7 @@ void initReflector(reflector) {
|
||||||
'parameters': const [],
|
'parameters': const [],
|
||||||
'annotations': const [
|
'annotations': const [
|
||||||
const Component(
|
const Component(
|
||||||
selector: '[soup]', appInjector: const [dep.DependencyComponent])
|
selector: '[soup]', viewInjector: const [dep.DependencyComponent])
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ void initReflector(reflector) {
|
||||||
'parameters': const [],
|
'parameters': const [],
|
||||||
'annotations': const [
|
'annotations': const [
|
||||||
const Component(
|
const Component(
|
||||||
selector: '[soup]', appInjector: const [dep.DependencyComponent])
|
selector: '[soup]', viewInjector: const [dep.DependencyComponent])
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
i0.initReflector(reflector);
|
i0.initReflector(reflector);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
ComponentRef,
|
ComponentRef,
|
||||||
DomRenderer
|
DomRenderer
|
||||||
} from 'angular2/angular2';
|
} from 'angular2/angular2';
|
||||||
import {bind, Injector, Injectable, forwardRef} from 'angular2/di';
|
import {bind, Injectable, forwardRef, ResolvedBinding, Injector} from 'angular2/di';
|
||||||
|
|
||||||
import {ObservableWrapper, Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
import {ObservableWrapper, Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {isPresent, Type} from 'angular2/src/facade/lang';
|
import {isPresent, Type} from 'angular2/src/facade/lang';
|
||||||
|
@ -46,17 +46,15 @@ export class MdDialog {
|
||||||
* @param options
|
* @param options
|
||||||
* @returns Promise for a reference to the dialog.
|
* @returns Promise for a reference to the dialog.
|
||||||
*/
|
*/
|
||||||
open(type: Type, elementRef: ElementRef, parentInjector: Injector,
|
open(type: Type, elementRef: ElementRef, options: MdDialogConfig = null): Promise<MdDialogRef> {
|
||||||
options: MdDialogConfig = null): Promise<MdDialogRef> {
|
|
||||||
var config = isPresent(options) ? options : new MdDialogConfig();
|
var config = isPresent(options) ? options : new MdDialogConfig();
|
||||||
|
|
||||||
// Create the dialogRef here so that it can be injected into the content component.
|
// Create the dialogRef here so that it can be injected into the content component.
|
||||||
var dialogRef = new MdDialogRef();
|
var dialogRef = new MdDialogRef();
|
||||||
|
|
||||||
var dialogRefBinding = bind(MdDialogRef).toValue(dialogRef);
|
var bindings = Injector.resolve([bind(MdDialogRef).toValue(dialogRef)]);
|
||||||
var contentInjector = parentInjector.resolveAndCreateChild([dialogRefBinding]);
|
|
||||||
|
|
||||||
var backdropRefPromise = this._openBackdrop(elementRef, contentInjector);
|
var backdropRefPromise = this._openBackdrop(elementRef, bindings);
|
||||||
|
|
||||||
// First, load the MdDialogContainer, into which the given component will be loaded.
|
// First, load the MdDialogContainer, into which the given component will be loaded.
|
||||||
return this.componentLoader.loadNextToLocation(MdDialogContainer, elementRef)
|
return this.componentLoader.loadNextToLocation(MdDialogContainer, elementRef)
|
||||||
|
@ -87,7 +85,7 @@ export class MdDialog {
|
||||||
|
|
||||||
// Now load the given component into the MdDialogContainer.
|
// Now load the given component into the MdDialogContainer.
|
||||||
return this.componentLoader.loadNextToLocation(type, containerRef.instance.contentRef,
|
return this.componentLoader.loadNextToLocation(type, containerRef.instance.contentRef,
|
||||||
contentInjector)
|
bindings)
|
||||||
.then(contentRef => {
|
.then(contentRef => {
|
||||||
|
|
||||||
// Wrap both component refs for the container and the content so that we can return
|
// Wrap both component refs for the container and the content so that we can return
|
||||||
|
@ -106,8 +104,8 @@ export class MdDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads the dialog backdrop (transparent overlay over the rest of the page). */
|
/** Loads the dialog backdrop (transparent overlay over the rest of the page). */
|
||||||
_openBackdrop(elementRef: ElementRef, injector: Injector): Promise<ComponentRef> {
|
_openBackdrop(elementRef: ElementRef, bindings: ResolvedBinding[]): Promise<ComponentRef> {
|
||||||
return this.componentLoader.loadNextToLocation(MdBackdrop, elementRef, injector)
|
return this.componentLoader.loadNextToLocation(MdBackdrop, elementRef, bindings)
|
||||||
.then((componentRef) => {
|
.then((componentRef) => {
|
||||||
// TODO(tbosch): clean this up when we have custom renderers
|
// TODO(tbosch): clean this up when we have custom renderers
|
||||||
// (https://github.com/angular/angular/issues/1807)
|
// (https://github.com/angular/angular/issues/1807)
|
||||||
|
|
|
@ -12,8 +12,6 @@ export function main() {
|
||||||
var iterations = getIntParameter('iterations');
|
var iterations = getIntParameter('iterations');
|
||||||
|
|
||||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||||
var appInjector = Injector.resolveAndCreate([]);
|
|
||||||
|
|
||||||
var bindings = [
|
var bindings = [
|
||||||
DirectiveBinding.createFromType(A, null),
|
DirectiveBinding.createFromType(A, null),
|
||||||
DirectiveBinding.createFromType(B, null),
|
DirectiveBinding.createFromType(B, null),
|
||||||
|
@ -25,14 +23,14 @@ export function main() {
|
||||||
function instantiate() {
|
function instantiate() {
|
||||||
for (var i = 0; i < iterations; ++i) {
|
for (var i = 0; i < iterations; ++i) {
|
||||||
var ei = proto.instantiate(null);
|
var ei = proto.instantiate(null);
|
||||||
ei.hydrate(appInjector, null, null);
|
ei.hydrate(null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hydrate() {
|
function hydrate() {
|
||||||
for (var i = 0; i < iterations; ++i) {
|
for (var i = 0; i < iterations; ++i) {
|
||||||
elementInjector.dehydrate();
|
elementInjector.dehydrate();
|
||||||
elementInjector.hydrate(appInjector, null, null);
|
elementInjector.hydrate(null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class RedDec {
|
||||||
selector: 'hello-app',
|
selector: 'hello-app',
|
||||||
// These are services that would be created if a class in the component's
|
// These are services that would be created if a class in the component's
|
||||||
// template tries to inject them.
|
// template tries to inject them.
|
||||||
appInjector: [GreetingService]
|
viewInjector: [GreetingService]
|
||||||
})
|
})
|
||||||
// The template for the component.
|
// The template for the component.
|
||||||
@View({
|
@View({
|
||||||
|
|
|
@ -6,13 +6,13 @@ import {
|
||||||
} from 'angular2_material/src/components/dialog/dialog';
|
} from 'angular2_material/src/components/dialog/dialog';
|
||||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||||
import {bind, Injector} from 'angular2/di';
|
import {bind} from 'angular2/di';
|
||||||
import {isPresent} from 'angular2/src/facade/lang';
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'demo-app',
|
selector: 'demo-app',
|
||||||
appInjector: [MdDialog],
|
viewInjector: [MdDialog],
|
||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
templateUrl: './demo_app.html',
|
templateUrl: './demo_app.html',
|
||||||
|
@ -23,14 +23,12 @@ class DemoApp {
|
||||||
elementRef: ElementRef;
|
elementRef: ElementRef;
|
||||||
dialogRef: MdDialogRef;
|
dialogRef: MdDialogRef;
|
||||||
dialogConfig: MdDialogConfig;
|
dialogConfig: MdDialogConfig;
|
||||||
injector: Injector;
|
|
||||||
lastResult: string;
|
lastResult: string;
|
||||||
|
|
||||||
constructor(mdDialog: MdDialog, elementRef: ElementRef, injector: Injector) {
|
constructor(mdDialog: MdDialog, elementRef: ElementRef) {
|
||||||
this.dialog = mdDialog;
|
this.dialog = mdDialog;
|
||||||
this.elementRef = elementRef;
|
this.elementRef = elementRef;
|
||||||
this.dialogConfig = new MdDialogConfig();
|
this.dialogConfig = new MdDialogConfig();
|
||||||
this.injector = injector;
|
|
||||||
|
|
||||||
this.dialogConfig.width = '60%';
|
this.dialogConfig.width = '60%';
|
||||||
this.dialogConfig.height = '60%';
|
this.dialogConfig.height = '60%';
|
||||||
|
@ -42,7 +40,7 @@ class DemoApp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dialog.open(SimpleDialogComponent, this.elementRef, this.injector, this.dialogConfig)
|
this.dialog.open(SimpleDialogComponent, this.elementRef, this.dialogConfig)
|
||||||
.then(ref => {
|
.then(ref => {
|
||||||
this.dialogRef = ref;
|
this.dialogRef = ref;
|
||||||
ref.instance.numCoconuts = 777;
|
ref.instance.numCoconuts = 777;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||||
import {bind} from 'angular2/di';
|
import {bind} from 'angular2/di';
|
||||||
|
|
||||||
@Component({selector: 'demo-app', appInjector: [MdRadioDispatcher]})
|
@Component({selector: 'demo-app', viewInjector: [MdRadioDispatcher]})
|
||||||
@View({templateUrl: './demo_app.html', directives: [MdRadioGroup, MdRadioButton]})
|
@View({templateUrl: './demo_app.html', directives: [MdRadioGroup, MdRadioButton]})
|
||||||
class DemoApp {
|
class DemoApp {
|
||||||
thirdValue;
|
thirdValue;
|
||||||
|
|
|
@ -72,7 +72,7 @@ class ShowError {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Component({selector: 'model-driven-forms', appInjector: [FormBuilder]})
|
@Component({selector: 'model-driven-forms', viewInjector: [FormBuilder]})
|
||||||
@View({
|
@View({
|
||||||
template: `
|
template: `
|
||||||
<h1>Checkout Form (Model Driven)</h1>
|
<h1>Checkout Form (Model Driven)</h1>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {Store, Todo, TodoFactory} from './services/TodoStore';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
|
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
|
||||||
|
|
||||||
@Component({selector: 'todo-app', appInjector: [Store, TodoFactory]})
|
@Component({selector: 'todo-app', viewInjector: [Store, TodoFactory]})
|
||||||
@View({templateUrl: 'todo.html', directives: [NgFor]})
|
@View({templateUrl: 'todo.html', directives: [NgFor]})
|
||||||
class TodoApp {
|
class TodoApp {
|
||||||
todoEdit: Todo = null;
|
todoEdit: Todo = null;
|
||||||
|
|
Loading…
Reference in New Issue