feat(di): rename Binding into Provider

Closes #4416

Closes #4654
This commit is contained in:
vsavkin
2015-10-10 22:11:13 -07:00
committed by Victor Savkin
parent 7c6130c2c5
commit 1eb0162cde
190 changed files with 2071 additions and 1816 deletions

View File

@ -18,11 +18,11 @@ export 'package:angular2/src/core/linker/dynamic_component_loader.dart' show Com
///
/// See [commonBootstrap] for detailed documentation.
Future<ComponentRef> bootstrap(Type appComponentType,
[List componentInjectableBindings]) {
[List componentInjectableProviders]) {
reflector.reflectionCapabilities = new ReflectionCapabilities();
var bindings = [compilerBindings()];
if (componentInjectableBindings != null) {
bindings.add(componentInjectableBindings);
var providers = [compilerProviders()];
if (componentInjectableProviders != null) {
providers.add(componentInjectableProviders);
}
return commonBootstrap(appComponentType, bindings);
return commonBootstrap(appComponentType, providers);
}

View File

@ -1,8 +1,8 @@
// Public API for Application
import {Binding} from './di';
import {Provider} from './di';
import {Type, isPresent} from 'angular2/src/core/facade/lang';
import {Promise} from 'angular2/src/core/facade/async';
import {compilerBindings} from 'angular2/src/core/compiler/compiler';
import {compilerProviders} from 'angular2/src/core/compiler/compiler';
import {commonBootstrap} from './application_common';
import {ComponentRef} from './linker/dynamic_component_loader';
@ -19,9 +19,9 @@ export {
/// See [commonBootstrap] for detailed documentation.
export function bootstrap(appComponentType: /*Type*/ any,
appBindings: Array<Type | Binding | any[]> = null):
appBindings: Array<Type | Provider | any[]> = null):
Promise<ComponentRef> {
var bindings = [compilerBindings()];
var bindings = [compilerProviders()];
if (isPresent(appBindings)) {
bindings.push(appBindings);
}

View File

@ -1,5 +1,5 @@
import {FORM_BINDINGS} from 'angular2/src/core/forms';
import {bind, Binding, Injector, OpaqueToken} from 'angular2/src/core/di';
import {FORM_PROVIDERS} from 'angular2/src/core/forms';
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
import {
NumberWrapper,
Type,
@ -34,37 +34,36 @@ import {
SharedStylesHost,
DomSharedStylesHost
} from 'angular2/src/core/render/dom/shared_styles_host';
import {EXCEPTION_BINDING} from './platform_bindings';
import {EXCEPTION_PROVIDER} from './platform_bindings';
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
import {BrowserDetails} from 'angular2/src/animate/browser_details';
import {wtfInit} from './profile/wtf_init';
import {platformCommon, PlatformRef, applicationCommonBindings} from './application_ref';
/**
* A default set of bindings which apply only to an Angular application running on
* A default set of providers which apply only to an Angular application running on
* the UI thread.
*/
export function applicationDomBindings(): Array<Type | Binding | any[]> {
export function applicationDomBindings(): Array<Type | Provider | any[]> {
if (isBlank(DOM)) {
throw "Must set a root DOM adapter first.";
}
return [
bind(DOCUMENT)
.toValue(DOM.defaultDoc()),
provide(DOCUMENT, {asValue: DOM.defaultDoc()}),
EventManager,
new Binding(EVENT_MANAGER_PLUGINS, {toClass: DomEventsPlugin, multi: true}),
new Binding(EVENT_MANAGER_PLUGINS, {toClass: KeyEventsPlugin, multi: true}),
new Binding(EVENT_MANAGER_PLUGINS, {toClass: HammerGesturesPlugin, multi: true}),
bind(DomRenderer).toClass(DomRenderer_),
bind(Renderer).toAlias(DomRenderer),
new Provider(EVENT_MANAGER_PLUGINS, {toClass: DomEventsPlugin, multi: true}),
new Provider(EVENT_MANAGER_PLUGINS, {toClass: KeyEventsPlugin, multi: true}),
new Provider(EVENT_MANAGER_PLUGINS, {toClass: HammerGesturesPlugin, multi: true}),
provide(DomRenderer, {asClass: DomRenderer_}),
provide(Renderer, {asAlias: DomRenderer}),
DomSharedStylesHost,
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
EXCEPTION_BINDING,
bind(XHR).toValue(new XHRImpl()),
provide(SharedStylesHost, {asAlias: DomSharedStylesHost}),
EXCEPTION_PROVIDER,
provide(XHR, {asValue: new XHRImpl()}),
Testability,
BrowserDetails,
AnimationBuilder,
FORM_BINDINGS
FORM_PROVIDERS
];
}
@ -73,25 +72,25 @@ export function applicationDomBindings(): Array<Type | Binding | any[]> {
*
* See {@link PlatformRef} for details on the Angular platform.
*
* # Without specified bindings
* # Without specified providers
*
* If no bindings are specified, `platform`'s behavior depends on whether an existing
* If no providers are specified, `platform`'s behavior depends on whether an existing
* platform exists:
*
* If no platform exists, a new one will be created with the default {@link platformBindings}.
*
* If a platform already exists, it will be returned (regardless of what bindings it
* If a platform already exists, it will be returned (regardless of what providers it
* was created with). This is a convenience feature, allowing for multiple applications
* to be loaded into the same platform without awareness of each other.
*
* # With specified bindings
* # With specified providers
*
* It is also possible to specify bindings to be made in the new platform. These bindings
* It is also possible to specify providers to be made in the new platform. These providers
* will be shared between all applications on the page. For example, an abstraction for
* the browser cookie jar should be bound at the platform level, because there is only one
* cookie jar regardless of how many applications on the age will be accessing it.
*
* If bindings are specified directly, `platform` will create the Angular platform with
* If providers are specified directly, `platform` will create the Angular platform with
* them if a platform did not exist already. If it did exist, however, an error will be
* thrown.
*
@ -101,7 +100,7 @@ export function applicationDomBindings(): Array<Type | Binding | any[]> {
* DOM access. Web-worker applications should call `platform` from
* `src/web_workers/worker/application_common` instead.
*/
export function platform(bindings?: Array<Type | Binding | any[]>): PlatformRef {
export function platform(bindings?: Array<Type | Provider | any[]>): PlatformRef {
return platformCommon(bindings, () => {
BrowserDomAdapter.makeCurrent();
wtfInit();
@ -129,10 +128,10 @@ export function platform(bindings?: Array<Type | Binding | any[]>): PlatformRef
* ```
*
* An application is bootstrapped inside an existing browser DOM, typically `index.html`.
* Unlike Angular 1, Angular 2 does not compile/process bindings in `index.html`. This is
* Unlike Angular 1, Angular 2 does not compile/process providers in `index.html`. This is
* mainly for security reasons, as well as architectural changes in Angular 2. This means
* that `index.html` can safely be processed using server-side technologies such as
* bindings. Bindings can thus use double-curly `{{ syntax }}` without collision from
* providers. Bindings can thus use double-curly `{{ syntax }}` without collision from
* Angular 2 component double-curly `{{ syntax }}`.
*
* We can use this script code:
@ -170,7 +169,7 @@ export function platform(bindings?: Array<Type | Binding | any[]>): PlatformRef
* 4. It creates a shadow DOM on the selected component's host element and loads the
* template into it.
* 5. It instantiates the specified component.
* 6. Finally, Angular performs change detection to apply the initial data bindings for the
* 6. Finally, Angular performs change detection to apply the initial data providers for the
* application.
*
*
@ -214,7 +213,7 @@ export function platform(bindings?: Array<Type | Binding | any[]>): PlatformRef
* # API
* - `appComponentType`: The root component which should act as the application. This is
* a reference to a `Type` which is annotated with `@Component(...)`.
* - `componentInjectableBindings`: An additional set of bindings that can be added to the
* - `componentInjectableBindings`: An additional set of providers that can be added to the
* app injector to override default injection behavior.
* - `errorReporter`: `function(exception:any, stackTrace:string)` a default error reporter
* for unhandled exceptions.
@ -222,7 +221,7 @@ export function platform(bindings?: Array<Type | Binding | any[]>): PlatformRef
* Returns a `Promise` of {@link ComponentRef}.
*/
export function commonBootstrap(appComponentType: /*Type*/ any,
appBindings: Array<Type | Binding | any[]> = null):
appBindings: Array<Type | Provider | any[]> = null):
Promise<ComponentRef> {
var p = platform();
var bindings = [applicationCommonBindings(), applicationDomBindings()];

View File

@ -1,10 +1,10 @@
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {Type, isBlank, isPresent, assertionsEnabled} from 'angular2/src/core/facade/lang';
import {bind, Binding, Injector, OpaqueToken} from 'angular2/src/core/di';
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
import {
APP_COMPONENT_REF_PROMISE,
APP_COMPONENT,
APP_ID_RANDOM_BINDING
APP_ID_RANDOM_PROVIDER
} from './application_tokens';
import {Promise, PromiseWrapper, PromiseCompleter} from 'angular2/src/core/facade/async';
import {ListWrapper} from 'angular2/src/core/facade/collection';
@ -44,67 +44,71 @@ import {AppViewManager_} from "./linker/view_manager";
import {Compiler_} from "./linker/compiler";
/**
* Constructs the set of bindings meant for use at the platform level.
* Constructs the set of providers meant for use at the platform level.
*
* These are bindings that should be singletons shared among all Angular applications
* These are providers that should be singletons shared among all Angular applications
* running on the page.
*/
export function platformBindings(): Array<Type | Binding | any[]> {
return [bind(Reflector).toValue(reflector), TestabilityRegistry];
export function platformBindings(): Array<Type | Provider | any[]> {
return [provide(Reflector, {asValue: reflector}), TestabilityRegistry];
}
/**
* Construct bindings specific to an individual root component.
* Construct providers specific to an individual root component.
*/
function _componentBindings(appComponentType: Type): Array<Type | Binding | any[]> {
function _componentProviders(appComponentType: Type): Array<Type | Provider | any[]> {
return [
bind(APP_COMPONENT)
.toValue(appComponentType),
bind(APP_COMPONENT_REF_PROMISE)
.toFactory(
(dynamicComponentLoader, injector: Injector) => {
// TODO(rado): investigate whether to support bindings on root component.
return dynamicComponentLoader.loadAsRoot(appComponentType, null, injector)
.then((componentRef) => {
if (isPresent(componentRef.location.nativeElement)) {
injector.get(TestabilityRegistry)
.registerApplication(componentRef.location.nativeElement,
injector.get(Testability));
}
return componentRef;
});
},
[DynamicComponentLoader, Injector]),
bind(appComponentType)
.toFactory((p: Promise<any>) => p.then(ref => ref.instance), [APP_COMPONENT_REF_PROMISE]),
provide(APP_COMPONENT, {asValue: appComponentType}),
provide(APP_COMPONENT_REF_PROMISE,
{
asFactory: (dynamicComponentLoader, injector: Injector) => {
// TODO(rado): investigate whether to support bindings on root component.
return dynamicComponentLoader.loadAsRoot(appComponentType, null, injector)
.then((componentRef) => {
if (isPresent(componentRef.location.nativeElement)) {
injector.get(TestabilityRegistry)
.registerApplication(componentRef.location.nativeElement,
injector.get(Testability));
}
return componentRef;
});
},
deps: [DynamicComponentLoader, Injector]
}),
provide(appComponentType,
{
asFactory: (p: Promise<any>) => p.then(ref => ref.instance),
deps: [APP_COMPONENT_REF_PROMISE]
}),
];
}
/**
* Construct a default set of bindings which should be included in any Angular
* Construct a default set of providers which should be included in any Angular
* application, regardless of whether it runs on the UI thread or in a web worker.
*/
export function applicationCommonBindings(): Array<Type | Binding | any[]> {
export function applicationCommonBindings(): Array<Type | Provider | any[]> {
return [
bind(Compiler)
.toClass(Compiler_),
APP_ID_RANDOM_BINDING,
provide(Compiler, {asClass: Compiler_}),
APP_ID_RANDOM_PROVIDER,
AppViewPool,
bind(APP_VIEW_POOL_CAPACITY).toValue(10000),
bind(AppViewManager).toClass(AppViewManager_),
provide(APP_VIEW_POOL_CAPACITY, {asValue: 10000}),
provide(AppViewManager, {asClass: AppViewManager_}),
AppViewManagerUtils,
AppViewListener,
ProtoViewFactory,
ViewResolver,
DEFAULT_PIPES,
bind(IterableDiffers).toValue(defaultIterableDiffers),
bind(KeyValueDiffers).toValue(defaultKeyValueDiffers),
provide(IterableDiffers, {asValue: defaultIterableDiffers}),
provide(KeyValueDiffers, {asValue: defaultKeyValueDiffers}),
DirectiveResolver,
PipeResolver,
bind(DynamicComponentLoader).toClass(DynamicComponentLoader_),
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle_(null, assertionsEnabled()),
[ExceptionHandler]),
provide(DynamicComponentLoader, {asClass: DynamicComponentLoader_}),
provide(LifeCycle,
{
asFactory: (exceptionHandler) => new LifeCycle_(null, assertionsEnabled()),
deps: [ExceptionHandler]
})
];
}
@ -117,7 +121,7 @@ export function createNgZone(): NgZone {
var _platform: PlatformRef;
export function platformCommon(bindings?: Array<Type | Binding | any[]>, initializer?: () => void):
export function platformCommon(bindings?: Array<Type | Provider | any[]>, initializer?: () => void):
PlatformRef {
if (isPresent(_platform)) {
if (isBlank(bindings)) {
@ -148,7 +152,7 @@ export function platformCommon(bindings?: Array<Type | Binding | any[]>, initial
export abstract class PlatformRef {
/**
* Retrieve the platform {@link Injector}, which is the parent injector for
* every Angular application on the page and provides singleton bindings.
* every Angular application on the page and provides singleton providers.
*/
get injector(): Injector { return unimplemented(); };
@ -163,10 +167,10 @@ export abstract class PlatformRef {
*
* # Application Bindings
*
* Angular applications require numerous bindings to be properly instantiated.
* When using `application()` to create a new app on the page, these bindings
* Angular applications require numerous providers to be properly instantiated.
* When using `application()` to create a new app on the page, these providers
* must be provided. Fortunately, there are helper functions to configure
* typical bindings, as shown in the example below.
* typical providers, as shown in the example below.
*
* # Example
* ```
@ -180,21 +184,21 @@ export abstract class PlatformRef {
*
* See the {@link bootstrap} documentation for more details.
*/
abstract application(bindings: Array<Type | Binding | any[]>): ApplicationRef;
abstract application(bindings: Array<Type | Provider | any[]>): ApplicationRef;
/**
* Instantiate a new Angular application on the page, using bindings which
* Instantiate a new Angular application on the page, using providers which
* are only available asynchronously. One such use case is to initialize an
* application running in a web worker.
*
* # Usage
*
* `bindingFn` is a function that will be called in the new application's zone.
* It should return a {@link Promise} to a list of bindings to be used for the
* It should return a {@link Promise} to a list of providers to be used for the
* new application. Once this promise resolves, the application will be
* constructed in the same manner as a normal `application()`.
*/
abstract asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Binding | any[]>>):
abstract asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>):
Promise<ApplicationRef>;
/**
@ -211,33 +215,33 @@ export class PlatformRef_ extends PlatformRef {
get injector(): Injector { return this._injector; }
application(bindings: Array<Type | Binding | any[]>): ApplicationRef {
application(bindings: Array<Type | Provider | any[]>): ApplicationRef {
var app = this._initApp(createNgZone(), bindings);
return app;
}
asyncApplication(bindingFn: (zone: NgZone) =>
Promise<Array<Type | Binding | any[]>>): Promise<ApplicationRef> {
Promise<Array<Type | Provider | any[]>>): Promise<ApplicationRef> {
var zone = createNgZone();
var completer = PromiseWrapper.completer();
zone.run(() => {
PromiseWrapper.then(bindingFn(zone), (bindings: Array<Type | Binding | any[]>) => {
PromiseWrapper.then(bindingFn(zone), (bindings: Array<Type | Provider | any[]>) => {
completer.resolve(this._initApp(zone, bindings));
});
});
return completer.promise;
}
private _initApp(zone: NgZone, bindings: Array<Type | Binding | any[]>): ApplicationRef {
private _initApp(zone: NgZone, providers: Array<Type | Provider | any[]>): ApplicationRef {
var injector: Injector;
var app: ApplicationRef;
zone.run(() => {
bindings.push(bind(NgZone).toValue(zone));
bindings.push(bind(ApplicationRef).toFactory((): ApplicationRef => app, []));
providers.push(provide(NgZone, {asValue: zone}));
providers.push(provide(ApplicationRef, {asFactory: (): ApplicationRef => app, deps: []}));
var exceptionHandler;
try {
injector = this.injector.resolveAndCreateChild(bindings);
injector = this.injector.resolveAndCreateChild(providers);
exceptionHandler = injector.get(ExceptionHandler);
zone.overrideOnErrorHandler((e, s) => exceptionHandler.call(e, s));
} catch (e) {
@ -285,18 +289,18 @@ export abstract class ApplicationRef {
*
* # Optional Bindings
*
* Bindings for the given component can optionally be overridden via the `bindings`
* parameter. These bindings will only apply for the root component being added and any
* Bindings for the given component can optionally be overridden via the `providers`
* parameter. These providers will only apply for the root component being added and any
* child components under it.
*
* # Example
* ```
* var app = platform.application([applicationCommonBindings(), applicationDomBindings()];
* app.bootstrap(FirstRootComponent);
* app.bootstrap(SecondRootComponent, [bind(OverrideBinding).toClass(OverriddenBinding)]);
* app.bootstrap(SecondRootComponent, [provide(OverrideBinding, {asClass: OverriddenBinding})]);
* ```
*/
abstract bootstrap(componentType: Type, bindings?: Array<Type | Binding | any[]>):
abstract bootstrap(componentType: Type, bindings?: Array<Type | Provider | any[]>):
Promise<ComponentRef>;
/**
@ -333,17 +337,18 @@ export class ApplicationRef_ extends ApplicationRef {
this._bootstrapListeners.push(listener);
}
bootstrap(componentType: Type, bindings?: Array<Type | Binding | any[]>): Promise<ComponentRef> {
bootstrap(componentType: Type,
providers?: Array<Type | Provider | any[]>): Promise<ComponentRef> {
var completer = PromiseWrapper.completer();
this._zone.run(() => {
var componentBindings = _componentBindings(componentType);
if (isPresent(bindings)) {
componentBindings.push(bindings);
var componentProviders = _componentProviders(componentType);
if (isPresent(providers)) {
componentProviders.push(providers);
}
var exceptionHandler = this._injector.get(ExceptionHandler);
this._rootComponentTypes.push(componentType);
try {
var injector: Injector = this._injector.resolveAndCreateChild(componentBindings);
var injector: Injector = this._injector.resolveAndCreateChild(componentProviders);
var compRefToken: Promise<ComponentRef> = injector.get(APP_COMPONENT_REF_PROMISE);
var tick = (componentRef) => {
var appChangeDetector = internalView(componentRef.hostView).changeDetector;

View File

@ -1,4 +1,4 @@
import {OpaqueToken, Binding} from 'angular2/src/core/di';
import {OpaqueToken, Provider} from 'angular2/src/core/di';
import {CONST_EXPR, Math, StringWrapper} from 'angular2/src/core/facade/lang';
/**
@ -31,20 +31,20 @@ export const APP_COMPONENT: OpaqueToken = CONST_EXPR(new OpaqueToken('AppCompone
* {@link ViewEncapsulation#Emulated} is being used.
*
* If you need to avoid randomly generated value to be used as an application id, you can provide
* a custom value via a DI binding <!-- TODO: provider --> configuring the root {@link Injector}
* a custom value via a DI provider <!-- TODO: provider --> configuring the root {@link Injector}
* using this token.
*/
export const APP_ID: OpaqueToken = CONST_EXPR(new OpaqueToken('AppId'));
function _appIdRandomBindingFactory() {
function _appIdRandomProviderFactory() {
return `${_randomChar()}${_randomChar()}${_randomChar()}`;
}
/**
* Bindings that will generate a random APP_ID_TOKEN.
*/
export const APP_ID_RANDOM_BINDING: Binding =
CONST_EXPR(new Binding(APP_ID, {toFactory: _appIdRandomBindingFactory, deps: []}));
export const APP_ID_RANDOM_PROVIDER: Provider =
CONST_EXPR(new Provider(APP_ID, {toFactory: _appIdRandomProviderFactory, deps: []}));
function _randomChar(): string {
return StringWrapper.fromCharCode(97 + Math.floor(Math.random() * 25));

View File

@ -85,7 +85,7 @@ export abstract class ChangeDetectorRef {
* }
*
* @Component({
* selector: 'app', bindings: [DataProvider]
* selector: 'app', providers: [DataProvider]
* })
* @View({
* template: `
@ -166,7 +166,7 @@ export abstract class ChangeDetectorRef {
*
* @Component({
* selector: 'app',
* bindings: [DataProvider]
* providers: [DataProvider]
* })
* @View({
* template: `

View File

@ -2,7 +2,7 @@ import {isBlank, isPresent, CONST} from 'angular2/src/core/facade/lang';
import {BaseException} from 'angular2/src/core/facade/exceptions';
import {ListWrapper} from 'angular2/src/core/facade/collection';
import {ChangeDetectorRef} from '../change_detector_ref';
import {Binding, SkipSelfMetadata, OptionalMetadata, Injectable} from 'angular2/src/core/di';
import {Provider, SkipSelfMetadata, OptionalMetadata, Injectable} from 'angular2/src/core/di';
export interface IterableDiffer {
diff(object: Object): any;
@ -36,7 +36,7 @@ export class IterableDiffers {
}
/**
* Takes an array of {@link IterableDifferFactory} and returns a binding used to extend the
* Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
* inherited {@link IterableDiffers} instance with the provided factories and return a new
* {@link IterableDiffers} instance.
*
@ -48,14 +48,14 @@ export class IterableDiffers {
*
* ```
* @Component({
* viewBindings: [
* viewProviders: [
* IterableDiffers.extend([new ImmutableListDiffer()])
* ]
* })
* ```
*/
static extend(factories: IterableDifferFactory[]): Binding {
return new Binding(IterableDiffers, {
static extend(factories: IterableDifferFactory[]): Provider {
return new Provider(IterableDiffers, {
toFactory: (parent: IterableDiffers) => {
if (isBlank(parent)) {
// Typically would occur when calling IterableDiffers.extend inside of dependencies passed

View File

@ -2,7 +2,7 @@ import {isBlank, isPresent, CONST} from 'angular2/src/core/facade/lang';
import {BaseException} from 'angular2/src/core/facade/exceptions';
import {ListWrapper} from 'angular2/src/core/facade/collection';
import {ChangeDetectorRef} from '../change_detector_ref';
import {Binding, SkipSelfMetadata, OptionalMetadata, Injectable} from 'angular2/src/core/di';
import {Provider, SkipSelfMetadata, OptionalMetadata, Injectable} from 'angular2/src/core/di';
export interface KeyValueDiffer {
diff(object: Object);
@ -36,7 +36,7 @@ export class KeyValueDiffers {
}
/**
* Takes an array of {@link KeyValueDifferFactory} and returns a binding used to extend the
* Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
* inherited {@link KeyValueDiffers} instance with the provided factories and return a new
* {@link KeyValueDiffers} instance.
*
@ -48,14 +48,14 @@ export class KeyValueDiffers {
*
* ```
* @Component({
* viewBindings: [
* viewProviders: [
* KeyValueDiffers.extend([new ImmutableMapDiffer()])
* ]
* })
* ```
*/
static extend(factories: KeyValueDifferFactory[]): Binding {
return new Binding(KeyValueDiffers, {
static extend(factories: KeyValueDifferFactory[]): Provider {
return new Provider(KeyValueDiffers, {
toFactory: (parent: KeyValueDiffers) => {
if (isBlank(parent)) {
// Typically would occur when calling KeyValueDiffers.extend inside of dependencies passed

View File

@ -8,7 +8,7 @@ export {
export {SourceModule, SourceWithImports} from './source_module';
import {assertionsEnabled, Type} from 'angular2/src/core/facade/lang';
import {bind, Binding} from 'angular2/src/core/di';
import {provide, Provider} from 'angular2/src/core/di';
import {TemplateParser} from 'angular2/src/core/compiler/template_parser';
import {HtmlParser} from 'angular2/src/core/compiler/html_parser';
import {TemplateNormalizer} from 'angular2/src/core/compiler/template_normalizer';
@ -29,7 +29,7 @@ import {AppRootUrl} from 'angular2/src/core/compiler/app_root_url';
import {AnchorBasedAppRootUrl} from 'angular2/src/core/compiler/anchor_based_app_root_url';
import {Parser, Lexer} from 'angular2/src/core/change_detection/change_detection';
export function compilerBindings(): Array<Type | Binding | any[]> {
export function compilerProviders(): Array<Type | Provider | any[]> {
return [
Lexer,
Parser,
@ -40,16 +40,18 @@ export function compilerBindings(): Array<Type | Binding | any[]> {
StyleCompiler,
CommandCompiler,
ChangeDetectionCompiler,
bind(ChangeDetectorGenConfig)
.toValue(
new ChangeDetectorGenConfig(assertionsEnabled(), assertionsEnabled(), false, true)),
provide(ChangeDetectorGenConfig,
{
asValue:
new ChangeDetectorGenConfig(assertionsEnabled(), assertionsEnabled(), false, true)
}),
TemplateCompiler,
bind(RuntimeCompiler).toClass(RuntimeCompiler_),
bind(Compiler).toAlias(RuntimeCompiler),
provide(RuntimeCompiler, {asClass: RuntimeCompiler_}),
provide(Compiler, {asAlias: RuntimeCompiler}),
DomElementSchemaRegistry,
bind(ElementSchemaRegistry).toAlias(DomElementSchemaRegistry),
provide(ElementSchemaRegistry, {asAlias: DomElementSchemaRegistry}),
AnchorBasedAppRootUrl,
bind(AppRootUrl).toAlias(AnchorBasedAppRootUrl),
provide(AppRootUrl, {asAlias: AnchorBasedAppRootUrl}),
UrlResolver
];
}

View File

@ -1,2 +1,6 @@
export {DebugElement, asNativeElements, By, Scope, inspectElement} from './debug/debug_element';
export {inspectNativeElement, ELEMENT_PROBE_BINDINGS} from './debug/debug_element_view_listener';
export {
inspectNativeElement,
ELEMENT_PROBE_PROVIDERS,
ELEMENT_PROBE_BINDINGS
} from './debug/debug_element_view_listener';

View File

@ -1,6 +1,6 @@
import {CONST_EXPR, isPresent, NumberWrapper, StringWrapper} from 'angular2/src/core/facade/lang';
import {MapWrapper, Map, ListWrapper} from 'angular2/src/core/facade/collection';
import {Injectable, bind, Binding} from 'angular2/src/core/di';
import {Injectable, provide, Provider} from 'angular2/src/core/di';
import {AppViewListener} from 'angular2/src/core/linker/view_listener';
import {AppView} from 'angular2/src/core/linker/view';
import {DOM} from 'angular2/src/core/dom/dom_adapter';
@ -67,7 +67,9 @@ export class DebugElementViewListener implements AppViewListener {
}
}
export const ELEMENT_PROBE_BINDINGS: any[] = CONST_EXPR([
export const ELEMENT_PROBE_PROVIDERS: any[] = CONST_EXPR([
DebugElementViewListener,
CONST_EXPR(new Binding(AppViewListener, {toAlias: DebugElementViewListener})),
CONST_EXPR(new Provider(AppViewListener, {toAlias: DebugElementViewListener})),
]);
export const ELEMENT_PROBE_BINDINGS = ELEMENT_PROBE_PROVIDERS;

View File

@ -21,19 +21,23 @@ export {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref';
export {Injector} from './di/injector';
export {
Binding,
BindingBuilder,
ProviderBuilder,
ResolvedBinding,
ResolvedFactory,
Dependency,
bind
} from './di/binding';
bind,
Provider,
ResolvedProvider,
provide
} from './di/provider';
export {Key, TypeLiteral} from './di/key';
export {
NoBindingError,
AbstractBindingError,
NoProviderError,
AbstractProviderError,
CyclicDependencyError,
InstantiationError,
InvalidBindingError,
InvalidProviderError,
NoAnnotationError,
OutOfBoundsError
} from './di/exceptions';

View File

@ -29,9 +29,9 @@ function constructResolvingPath(keys: any[]): string {
/**
* Base class for all errors arising from misconfigured bindings.
* Base class for all errors arising from misconfigured providers.
*/
export class AbstractBindingError extends BaseException {
export class AbstractProviderError extends BaseException {
/** @internal */
message: string;
@ -63,7 +63,7 @@ export class AbstractBindingError extends BaseException {
/**
* Thrown when trying to retrieve a dependency by `Key` from {@link Injector}, but the
* {@link Injector} does not have a {@link Binding} for {@link Key}.
* {@link Injector} does not have a {@link Provider} for {@link Key}.
*
* ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
*
@ -75,7 +75,7 @@ export class AbstractBindingError extends BaseException {
* expect(() => Injector.resolveAndCreate([A])).toThrowError();
* ```
*/
export class NoBindingError extends AbstractBindingError {
export class NoProviderError extends AbstractProviderError {
constructor(injector: Injector, key: Key) {
super(injector, key, function(keys: any[]) {
var first = stringify(ListWrapper.first(keys).token);
@ -91,8 +91,8 @@ export class NoBindingError extends AbstractBindingError {
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* bind("one").toFactory((two) => "two", [[new Inject("two")]]),
* bind("two").toFactory((one) => "one", [[new Inject("one")]])
* provide("one", {asFactory: (two) => "two", deps: [[new Inject("two")]]}),
* provide("two", {asFactory: (one) => "one", deps: [[new Inject("one")]]})
* ]);
*
* expect(() => injector.get("one")).toThrowError();
@ -100,7 +100,7 @@ export class NoBindingError extends AbstractBindingError {
*
* Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
*/
export class CyclicDependencyError extends AbstractBindingError {
export class CyclicDependencyError extends AbstractProviderError {
constructor(injector: Injector, key: Key) {
super(injector, key, function(keys: any[]) {
return `Cannot instantiate cyclic dependency!${constructResolvingPath(keys)}`;
@ -163,7 +163,7 @@ export class InstantiationError extends WrappedException {
}
/**
* Thrown when an object other then {@link Binding} (or `Type`) is passed to {@link Injector}
* Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
* creation.
*
* ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
@ -172,10 +172,10 @@ export class InstantiationError extends WrappedException {
* expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
* ```
*/
export class InvalidBindingError extends BaseException {
constructor(binding) {
super("Invalid binding - only instances of Binding and Type are allowed, got: " +
binding.toString());
export class InvalidProviderError extends BaseException {
constructor(provider) {
super("Invalid provider - only instances of Provider and Type are allowed, got: " +
provider.toString());
}
}
@ -246,20 +246,20 @@ export class OutOfBoundsError extends BaseException {
// TODO: add a working example after alpha38 is released
/**
* Thrown when a multi binding and a regular binding are bound to the same token.
* Thrown when a multi provider and a regular provider are bound to the same token.
*
* ### Example
*
* ```typescript
* expect(() => Injector.resolveAndCreate([
* new Binding("Strings", {toValue: "string1", multi: true}),
* new Binding("Strings", {toValue: "string2", multi: false})
* new Provider("Strings", {toValue: "string1", multi: true}),
* new Provider("Strings", {toValue: "string2", multi: false})
* ])).toThrowError();
* ```
*/
export class MixingMultiBindingsWithRegularBindings extends BaseException {
constructor(binding1, binding2) {
super("Cannot mix multi bindings and regular bindings, got: " + binding1.toString() + " " +
binding2.toString());
export class MixingMultiProvidersWithRegularProvidersError extends BaseException {
constructor(provider1, provider2) {
super("Cannot mix multi providers and regular providers, got: " + provider1.toString() + " " +
provider2.toString());
}
}

View File

@ -1,21 +1,20 @@
import {Map, MapWrapper, ListWrapper} from 'angular2/src/core/facade/collection';
import {
ResolvedBinding,
Binding,
ResolvedProvider,
Provider,
Dependency,
BindingBuilder,
ProviderBuilder,
ResolvedFactory,
bind,
resolveBindings
} from './binding';
provide,
resolveProviders
} from './provider';
import {
AbstractBindingError,
NoBindingError,
AbstractProviderError,
NoProviderError,
CyclicDependencyError,
InstantiationError,
InvalidBindingError,
OutOfBoundsError,
MixingMultiBindingsWithRegularBindings
InvalidProviderError,
OutOfBoundsError
} from './exceptions';
import {FunctionWrapper, Type, isPresent, isBlank, CONST_EXPR} from 'angular2/src/core/facade/lang';
import {Key} from './key';
@ -28,19 +27,19 @@ const _MAX_CONSTRUCTION_COUNTER = 10;
export const UNDEFINED: Object = CONST_EXPR(new Object());
/**
* Visibility of a {@link Binding}.
* Visibility of a {@link Provider}.
*/
export enum Visibility {
/**
* A `Public` {@link Binding} is only visible to regular (as opposed to host) child injectors.
* A `Public` {@link Provider} is only visible to regular (as opposed to host) child injectors.
*/
Public,
/**
* A `Private` {@link Binding} is only visible to host (as opposed to regular) child injectors.
* A `Private` {@link Provider} is only visible to host (as opposed to regular) child injectors.
*/
Private,
/**
* A `PublicAndPrivate` {@link Binding} is visible to both host and regular child injectors.
* A `PublicAndPrivate` {@link Provider} is visible to both host and regular child injectors.
*/
PublicAndPrivate
}
@ -52,21 +51,21 @@ function canSee(src: Visibility, dst: Visibility): boolean {
export interface ProtoInjectorStrategy {
getBindingAtIndex(index: number): ResolvedBinding;
getProviderAtIndex(index: number): ResolvedProvider;
createInjectorStrategy(inj: Injector): InjectorStrategy;
}
export class ProtoInjectorInlineStrategy implements ProtoInjectorStrategy {
binding0: ResolvedBinding = null;
binding1: ResolvedBinding = null;
binding2: ResolvedBinding = null;
binding3: ResolvedBinding = null;
binding4: ResolvedBinding = null;
binding5: ResolvedBinding = null;
binding6: ResolvedBinding = null;
binding7: ResolvedBinding = null;
binding8: ResolvedBinding = null;
binding9: ResolvedBinding = null;
provider0: ResolvedProvider = null;
provider1: ResolvedProvider = null;
provider2: ResolvedProvider = null;
provider3: ResolvedProvider = null;
provider4: ResolvedProvider = null;
provider5: ResolvedProvider = null;
provider6: ResolvedProvider = null;
provider7: ResolvedProvider = null;
provider8: ResolvedProvider = null;
provider9: ResolvedProvider = null;
keyId0: number = null;
keyId1: number = null;
@ -90,72 +89,72 @@ export class ProtoInjectorInlineStrategy implements ProtoInjectorStrategy {
visibility8: Visibility = null;
visibility9: Visibility = null;
constructor(protoEI: ProtoInjector, bwv: BindingWithVisibility[]) {
constructor(protoEI: ProtoInjector, bwv: ProviderWithVisibility[]) {
var length = bwv.length;
if (length > 0) {
this.binding0 = bwv[0].binding;
this.provider0 = bwv[0].provider;
this.keyId0 = bwv[0].getKeyId();
this.visibility0 = bwv[0].visibility;
}
if (length > 1) {
this.binding1 = bwv[1].binding;
this.provider1 = bwv[1].provider;
this.keyId1 = bwv[1].getKeyId();
this.visibility1 = bwv[1].visibility;
}
if (length > 2) {
this.binding2 = bwv[2].binding;
this.provider2 = bwv[2].provider;
this.keyId2 = bwv[2].getKeyId();
this.visibility2 = bwv[2].visibility;
}
if (length > 3) {
this.binding3 = bwv[3].binding;
this.provider3 = bwv[3].provider;
this.keyId3 = bwv[3].getKeyId();
this.visibility3 = bwv[3].visibility;
}
if (length > 4) {
this.binding4 = bwv[4].binding;
this.provider4 = bwv[4].provider;
this.keyId4 = bwv[4].getKeyId();
this.visibility4 = bwv[4].visibility;
}
if (length > 5) {
this.binding5 = bwv[5].binding;
this.provider5 = bwv[5].provider;
this.keyId5 = bwv[5].getKeyId();
this.visibility5 = bwv[5].visibility;
}
if (length > 6) {
this.binding6 = bwv[6].binding;
this.provider6 = bwv[6].provider;
this.keyId6 = bwv[6].getKeyId();
this.visibility6 = bwv[6].visibility;
}
if (length > 7) {
this.binding7 = bwv[7].binding;
this.provider7 = bwv[7].provider;
this.keyId7 = bwv[7].getKeyId();
this.visibility7 = bwv[7].visibility;
}
if (length > 8) {
this.binding8 = bwv[8].binding;
this.provider8 = bwv[8].provider;
this.keyId8 = bwv[8].getKeyId();
this.visibility8 = bwv[8].visibility;
}
if (length > 9) {
this.binding9 = bwv[9].binding;
this.provider9 = bwv[9].provider;
this.keyId9 = bwv[9].getKeyId();
this.visibility9 = bwv[9].visibility;
}
}
getBindingAtIndex(index: number): any {
if (index == 0) return this.binding0;
if (index == 1) return this.binding1;
if (index == 2) return this.binding2;
if (index == 3) return this.binding3;
if (index == 4) return this.binding4;
if (index == 5) return this.binding5;
if (index == 6) return this.binding6;
if (index == 7) return this.binding7;
if (index == 8) return this.binding8;
if (index == 9) return this.binding9;
getProviderAtIndex(index: number): any {
if (index == 0) return this.provider0;
if (index == 1) return this.provider1;
if (index == 2) return this.provider2;
if (index == 3) return this.provider3;
if (index == 4) return this.provider4;
if (index == 5) return this.provider5;
if (index == 6) return this.provider6;
if (index == 7) return this.provider7;
if (index == 8) return this.provider8;
if (index == 9) return this.provider9;
throw new OutOfBoundsError(index);
}
@ -165,29 +164,29 @@ export class ProtoInjectorInlineStrategy implements ProtoInjectorStrategy {
}
export class ProtoInjectorDynamicStrategy implements ProtoInjectorStrategy {
bindings: ResolvedBinding[];
providers: ResolvedProvider[];
keyIds: number[];
visibilities: Visibility[];
constructor(protoInj: ProtoInjector, bwv: BindingWithVisibility[]) {
constructor(protoInj: ProtoInjector, bwv: ProviderWithVisibility[]) {
var len = bwv.length;
this.bindings = ListWrapper.createFixedSize(len);
this.providers = ListWrapper.createFixedSize(len);
this.keyIds = ListWrapper.createFixedSize(len);
this.visibilities = ListWrapper.createFixedSize(len);
for (var i = 0; i < len; i++) {
this.bindings[i] = bwv[i].binding;
this.providers[i] = bwv[i].provider;
this.keyIds[i] = bwv[i].getKeyId();
this.visibilities[i] = bwv[i].visibility;
}
}
getBindingAtIndex(index: number): any {
if (index < 0 || index >= this.bindings.length) {
getProviderAtIndex(index: number): any {
if (index < 0 || index >= this.providers.length) {
throw new OutOfBoundsError(index);
}
return this.bindings[index];
return this.providers[index];
}
createInjectorStrategy(ei: Injector): InjectorStrategy {
@ -198,16 +197,16 @@ export class ProtoInjectorDynamicStrategy implements ProtoInjectorStrategy {
export class ProtoInjector {
/** @internal */
_strategy: ProtoInjectorStrategy;
numberOfBindings: number;
numberOfProviders: number;
constructor(bwv: BindingWithVisibility[]) {
this.numberOfBindings = bwv.length;
constructor(bwv: ProviderWithVisibility[]) {
this.numberOfProviders = bwv.length;
this._strategy = bwv.length > _MAX_CONSTRUCTION_COUNTER ?
new ProtoInjectorDynamicStrategy(this, bwv) :
new ProtoInjectorInlineStrategy(this, bwv);
}
getBindingAtIndex(index: number): any { return this._strategy.getBindingAtIndex(index); }
getProviderAtIndex(index: number): any { return this._strategy.getProviderAtIndex(index); }
}
@ -219,7 +218,7 @@ export interface InjectorStrategy {
attach(parent: Injector, isHost: boolean): void;
resetConstructionCounter(): void;
instantiateBinding(binding: ResolvedBinding, visibility: Visibility): any;
instantiateProvider(provider: ResolvedProvider, visibility: Visibility): any;
}
export class InjectorInlineStrategy implements InjectorStrategy {
@ -238,8 +237,8 @@ export class InjectorInlineStrategy implements InjectorStrategy {
resetConstructionCounter(): void { this.injector._constructionCounter = 0; }
instantiateBinding(binding: ResolvedBinding, visibility: Visibility): any {
return this.injector._new(binding, visibility);
instantiateProvider(provider: ResolvedProvider, visibility: Visibility): any {
return this.injector._new(provider, visibility);
}
attach(parent: Injector, isHost: boolean): void {
@ -254,61 +253,61 @@ export class InjectorInlineStrategy implements InjectorStrategy {
if (p.keyId0 === keyId && canSee(p.visibility0, visibility)) {
if (this.obj0 === UNDEFINED) {
this.obj0 = inj._new(p.binding0, p.visibility0);
this.obj0 = inj._new(p.provider0, p.visibility0);
}
return this.obj0;
}
if (p.keyId1 === keyId && canSee(p.visibility1, visibility)) {
if (this.obj1 === UNDEFINED) {
this.obj1 = inj._new(p.binding1, p.visibility1);
this.obj1 = inj._new(p.provider1, p.visibility1);
}
return this.obj1;
}
if (p.keyId2 === keyId && canSee(p.visibility2, visibility)) {
if (this.obj2 === UNDEFINED) {
this.obj2 = inj._new(p.binding2, p.visibility2);
this.obj2 = inj._new(p.provider2, p.visibility2);
}
return this.obj2;
}
if (p.keyId3 === keyId && canSee(p.visibility3, visibility)) {
if (this.obj3 === UNDEFINED) {
this.obj3 = inj._new(p.binding3, p.visibility3);
this.obj3 = inj._new(p.provider3, p.visibility3);
}
return this.obj3;
}
if (p.keyId4 === keyId && canSee(p.visibility4, visibility)) {
if (this.obj4 === UNDEFINED) {
this.obj4 = inj._new(p.binding4, p.visibility4);
this.obj4 = inj._new(p.provider4, p.visibility4);
}
return this.obj4;
}
if (p.keyId5 === keyId && canSee(p.visibility5, visibility)) {
if (this.obj5 === UNDEFINED) {
this.obj5 = inj._new(p.binding5, p.visibility5);
this.obj5 = inj._new(p.provider5, p.visibility5);
}
return this.obj5;
}
if (p.keyId6 === keyId && canSee(p.visibility6, visibility)) {
if (this.obj6 === UNDEFINED) {
this.obj6 = inj._new(p.binding6, p.visibility6);
this.obj6 = inj._new(p.provider6, p.visibility6);
}
return this.obj6;
}
if (p.keyId7 === keyId && canSee(p.visibility7, visibility)) {
if (this.obj7 === UNDEFINED) {
this.obj7 = inj._new(p.binding7, p.visibility7);
this.obj7 = inj._new(p.provider7, p.visibility7);
}
return this.obj7;
}
if (p.keyId8 === keyId && canSee(p.visibility8, visibility)) {
if (this.obj8 === UNDEFINED) {
this.obj8 = inj._new(p.binding8, p.visibility8);
this.obj8 = inj._new(p.provider8, p.visibility8);
}
return this.obj8;
}
if (p.keyId9 === keyId && canSee(p.visibility9, visibility)) {
if (this.obj9 === UNDEFINED) {
this.obj9 = inj._new(p.binding9, p.visibility9);
this.obj9 = inj._new(p.provider9, p.visibility9);
}
return this.obj9;
}
@ -338,14 +337,14 @@ export class InjectorDynamicStrategy implements InjectorStrategy {
objs: any[];
constructor(public protoStrategy: ProtoInjectorDynamicStrategy, public injector: Injector) {
this.objs = ListWrapper.createFixedSize(protoStrategy.bindings.length);
this.objs = ListWrapper.createFixedSize(protoStrategy.providers.length);
ListWrapper.fill(this.objs, UNDEFINED);
}
resetConstructionCounter(): void { this.injector._constructionCounter = 0; }
instantiateBinding(binding: ResolvedBinding, visibility: Visibility): any {
return this.injector._new(binding, visibility);
instantiateProvider(provider: ResolvedProvider, visibility: Visibility): any {
return this.injector._new(provider, visibility);
}
attach(parent: Injector, isHost: boolean): void {
@ -360,7 +359,7 @@ export class InjectorDynamicStrategy implements InjectorStrategy {
for (var i = 0; i < p.keyIds.length; i++) {
if (p.keyIds[i] === keyId && canSee(p.visibilities[i], visibility)) {
if (this.objs[i] === UNDEFINED) {
this.objs[i] = this.injector._new(p.bindings[i], p.visibilities[i]);
this.objs[i] = this.injector._new(p.providers[i], p.visibilities[i]);
}
return this.objs[i];
@ -381,17 +380,17 @@ export class InjectorDynamicStrategy implements InjectorStrategy {
getMaxNumberOfObjects(): number { return this.objs.length; }
}
export class BindingWithVisibility {
constructor(public binding: ResolvedBinding, public visibility: Visibility){};
export class ProviderWithVisibility {
constructor(public provider: ResolvedProvider, public visibility: Visibility){};
getKeyId(): number { return this.binding.key.id; }
getKeyId(): number { return this.provider.key.id; }
}
/**
* Used to provide dependencies that cannot be easily expressed as bindings.
* Used to provide dependencies that cannot be easily expressed as providers.
*/
export interface DependencyProvider {
getDependency(injector: Injector, binding: ResolvedBinding, dependency: Dependency): any;
getDependency(injector: Injector, provider: ResolvedProvider, dependency: Dependency): any;
}
/**
@ -428,10 +427,10 @@ export interface DependencyProvider {
*/
export class Injector {
/**
* Turns an array of binding definitions into an array of resolved bindings.
* Turns an array of provider definitions into an array of resolved providers.
*
* A resolution is a process of flattening multiple nested arrays and converting individual
* bindings into an array of {@link ResolvedBinding}s.
* providers into an array of {@link ResolvedProvider}s.
*
* ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
*
@ -445,30 +444,30 @@ export class Injector {
* constructor(public engine:Engine) {}
* }
*
* var bindings = Injector.resolve([Car, [[Engine]]]);
* var providers = Injector.resolve([Car, [[Engine]]]);
*
* expect(bindings.length).toEqual(2);
* expect(providers.length).toEqual(2);
*
* expect(bindings[0] instanceof ResolvedBinding).toBe(true);
* expect(bindings[0].key.displayName).toBe("Car");
* expect(bindings[0].dependencies.length).toEqual(1);
* expect(bindings[0].factory).toBeDefined();
* expect(providers[0] instanceof ResolvedProvider).toBe(true);
* expect(providers[0].key.displayName).toBe("Car");
* expect(providers[0].dependencies.length).toEqual(1);
* expect(providers[0].factory).toBeDefined();
*
* expect(bindings[1].key.displayName).toBe("Engine");
* expect(providers[1].key.displayName).toBe("Engine");
* });
* ```
*
* See {@link fromResolvedBindings} for more info.
* See {@link fromResolvedProviders} for more info.
*/
static resolve(bindings: Array<Type | Binding | any[]>): ResolvedBinding[] {
return resolveBindings(bindings);
static resolve(providers: Array<Type | Provider | any[]>): ResolvedProvider[] {
return resolveProviders(providers);
}
/**
* Resolves an array of bindings and creates an injector from those bindings.
* Resolves an array of providers and creates an injector from those providers.
*
* The passed-in bindings can be an array of `Type`, {@link Binding},
* or a recursive array of more bindings.
* The passed-in providers can be an array of `Type`, {@link Provider},
* or a recursive array of more providers.
*
* ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
*
@ -486,17 +485,17 @@ export class Injector {
* expect(injector.get(Car) instanceof Car).toBe(true);
* ```
*
* This function is slower than the corresponding `fromResolvedBindings`
* because it needs to resolve the passed-in bindings first.
* See {@link resolve} and {@link fromResolvedBindings}.
* This function is slower than the corresponding `fromResolvedProviders`
* because it needs to resolve the passed-in providers first.
* See {@link resolve} and {@link fromResolvedProviders}.
*/
static resolveAndCreate(bindings: Array<Type | Binding | any[]>): Injector {
var resolvedBindings = Injector.resolve(bindings);
return Injector.fromResolvedBindings(resolvedBindings);
static resolveAndCreate(providers: Array<Type | Provider | any[]>): Injector {
var resolvedProviders = Injector.resolve(providers);
return Injector.fromResolvedProviders(resolvedProviders);
}
/**
* Creates an injector from previously resolved bindings.
* Creates an injector from previously resolved providers.
*
* This API is the recommended way to construct injectors in performance-sensitive parts.
*
@ -512,17 +511,24 @@ export class Injector {
* constructor(public engine:Engine) {}
* }
*
* var bindings = Injector.resolve([Car, Engine]);
* var injector = Injector.fromResolvedBindings(bindings);
* var providers = Injector.resolve([Car, Engine]);
* var injector = Injector.fromResolvedProviders(providers);
* expect(injector.get(Car) instanceof Car).toBe(true);
* ```
*/
static fromResolvedBindings(bindings: ResolvedBinding[]): Injector {
var bd = bindings.map(b => new BindingWithVisibility(b, Visibility.Public));
static fromResolvedProviders(providers: ResolvedProvider[]): Injector {
var bd = providers.map(b => new ProviderWithVisibility(b, Visibility.Public));
var proto = new ProtoInjector(bd);
return new Injector(proto, null, null);
}
/**
* @deprecated
*/
static fromResolvedBindings(providers: ResolvedProvider[]): Injector {
return Injector.fromResolvedProviders(providers);
}
/** @internal */
_strategy: InjectorStrategy;
/** @internal */
@ -551,13 +557,13 @@ export class Injector {
/**
* Retrieves an instance from the injector based on the provided token.
* Throws {@link NoBindingError} if not found.
* Throws {@link NoProviderError} if not found.
*
* ### Example ([live demo](http://plnkr.co/edit/HeXSHg?p=preview))
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* bind("validToken").toValue("Value")
* provide("validToken", {asValue: "Value"})
* ]);
* expect(injector.get("validToken")).toEqual("Value");
* expect(() => injector.get("invalidToken")).toThrowError();
@ -582,7 +588,7 @@ export class Injector {
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* bind("validToken").toValue("Value")
* provide("validToken", {asValue: "Value"})
* ]);
* expect(injector.getOptional("validToken")).toEqual("Value");
* expect(injector.getOptional("invalidToken")).toBe(null);
@ -628,39 +634,39 @@ export class Injector {
get internalStrategy(): any { return this._strategy; }
/**
* Resolves an array of bindings and creates a child injector from those bindings.
* Resolves an array of providers and creates a child injector from those providers.
*
* <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
* -->
*
* The passed-in bindings can be an array of `Type`, {@link Binding},
* or a recursive array of more bindings.
* The passed-in providers can be an array of `Type`, {@link Provider},
* or a recursive array of more providers.
*
* ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview))
*
* ```typescript
* class ParentBinding {}
* class ChildBinding {}
* class ParentProvider {}
* class ChildProvider {}
*
* var parent = Injector.resolveAndCreate([ParentBinding]);
* var child = parent.resolveAndCreateChild([ChildBinding]);
* var parent = Injector.resolveAndCreate([ParentProvider]);
* var child = parent.resolveAndCreateChild([ChildProvider]);
*
* expect(child.get(ParentBinding) instanceof ParentBinding).toBe(true);
* expect(child.get(ChildBinding) instanceof ChildBinding).toBe(true);
* expect(child.get(ParentBinding)).toBe(parent.get(ParentBinding));
* expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
* expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
* expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
* ```
*
* This function is slower than the corresponding `createChildFromResolved`
* because it needs to resolve the passed-in bindings first.
* because it needs to resolve the passed-in providers first.
* See {@link resolve} and {@link createChildFromResolved}.
*/
resolveAndCreateChild(bindings: Array<Type | Binding | any[]>): Injector {
var resolvedBindings = Injector.resolve(bindings);
return this.createChildFromResolved(resolvedBindings);
resolveAndCreateChild(providers: Array<Type | Provider | any[]>): Injector {
var resolvedProviders = Injector.resolve(providers);
return this.createChildFromResolved(resolvedProviders);
}
/**
* Creates a child injector from previously resolved bindings.
* Creates a child injector from previously resolved providers.
*
* <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
* -->
@ -670,22 +676,22 @@ export class Injector {
* ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview))
*
* ```typescript
* class ParentBinding {}
* class ChildBinding {}
* class ParentProvider {}
* class ChildProvider {}
*
* var parentBindings = Injector.resolve([ParentBinding]);
* var childBindings = Injector.resolve([ChildBinding]);
* var parentProviders = Injector.resolve([ParentProvider]);
* var childProviders = Injector.resolve([ChildProvider]);
*
* var parent = Injector.fromResolvedBindings(parentBindings);
* var child = parent.createChildFromResolved(childBindings);
* var parent = Injector.fromResolvedProviders(parentProviders);
* var child = parent.createChildFromResolved(childProviders);
*
* expect(child.get(ParentBinding) instanceof ParentBinding).toBe(true);
* expect(child.get(ChildBinding) instanceof ChildBinding).toBe(true);
* expect(child.get(ParentBinding)).toBe(parent.get(ParentBinding));
* expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
* expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
* expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
* ```
*/
createChildFromResolved(bindings: ResolvedBinding[]): Injector {
var bd = bindings.map(b => new BindingWithVisibility(b, Visibility.Public));
createChildFromResolved(providers: ResolvedProvider[]): Injector {
var bd = providers.map(b => new ProviderWithVisibility(b, Visibility.Public));
var proto = new ProtoInjector(bd);
var inj = new Injector(proto, null, null);
inj._parent = this;
@ -693,7 +699,7 @@ export class Injector {
}
/**
* Resolves a binding and instantiates an object in the context of the injector.
* Resolves a provider and instantiates an object in the context of the injector.
*
* The created object does not get cached by the injector.
*
@ -716,12 +722,12 @@ export class Injector {
* expect(car).not.toBe(injector.resolveAndInstantiate(Car));
* ```
*/
resolveAndInstantiate(binding: Type | Binding): any {
return this.instantiateResolved(Injector.resolve([binding])[0]);
resolveAndInstantiate(provider: Type | Provider): any {
return this.instantiateResolved(Injector.resolve([provider])[0]);
}
/**
* Instantiates an object using a resolved binding in the context of the injector.
* Instantiates an object using a resolved provider in the context of the injector.
*
* The created object does not get cached by the injector.
*
@ -738,37 +744,37 @@ export class Injector {
* }
*
* var injector = Injector.resolveAndCreate([Engine]);
* var carBinding = Injector.resolve([Car])[0];
* var car = injector.instantiateResolved(carBinding);
* var carProvider = Injector.resolve([Car])[0];
* var car = injector.instantiateResolved(carProvider);
* expect(car.engine).toBe(injector.get(Engine));
* expect(car).not.toBe(injector.instantiateResolved(carBinding));
* expect(car).not.toBe(injector.instantiateResolved(carProvider));
* ```
*/
instantiateResolved(binding: ResolvedBinding): any {
return this._instantiateBinding(binding, Visibility.PublicAndPrivate);
instantiateResolved(provider: ResolvedProvider): any {
return this._instantiateProvider(provider, Visibility.PublicAndPrivate);
}
/** @internal */
_new(binding: ResolvedBinding, visibility: Visibility): any {
_new(provider: ResolvedProvider, visibility: Visibility): any {
if (this._constructionCounter++ > this._strategy.getMaxNumberOfObjects()) {
throw new CyclicDependencyError(this, binding.key);
throw new CyclicDependencyError(this, provider.key);
}
return this._instantiateBinding(binding, visibility);
return this._instantiateProvider(provider, visibility);
}
private _instantiateBinding(binding: ResolvedBinding, visibility: Visibility): any {
if (binding.multiBinding) {
var res = ListWrapper.createFixedSize(binding.resolvedFactories.length);
for (var i = 0; i < binding.resolvedFactories.length; ++i) {
res[i] = this._instantiate(binding, binding.resolvedFactories[i], visibility);
private _instantiateProvider(provider: ResolvedProvider, visibility: Visibility): any {
if (provider.multiProvider) {
var res = ListWrapper.createFixedSize(provider.resolvedFactories.length);
for (var i = 0; i < provider.resolvedFactories.length; ++i) {
res[i] = this._instantiate(provider, provider.resolvedFactories[i], visibility);
}
return res;
} else {
return this._instantiate(binding, binding.resolvedFactories[0], visibility);
return this._instantiate(provider, provider.resolvedFactories[0], visibility);
}
}
private _instantiate(binding: ResolvedBinding, resolvedFactory: ResolvedFactory,
private _instantiate(provider: ResolvedProvider, resolvedFactory: ResolvedFactory,
visibility: Visibility): any {
var factory = resolvedFactory.factory;
var deps = resolvedFactory.dependencies;
@ -776,29 +782,29 @@ export class Injector {
var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19;
try {
d0 = length > 0 ? this._getByDependency(binding, deps[0], visibility) : null;
d1 = length > 1 ? this._getByDependency(binding, deps[1], visibility) : null;
d2 = length > 2 ? this._getByDependency(binding, deps[2], visibility) : null;
d3 = length > 3 ? this._getByDependency(binding, deps[3], visibility) : null;
d4 = length > 4 ? this._getByDependency(binding, deps[4], visibility) : null;
d5 = length > 5 ? this._getByDependency(binding, deps[5], visibility) : null;
d6 = length > 6 ? this._getByDependency(binding, deps[6], visibility) : null;
d7 = length > 7 ? this._getByDependency(binding, deps[7], visibility) : null;
d8 = length > 8 ? this._getByDependency(binding, deps[8], visibility) : null;
d9 = length > 9 ? this._getByDependency(binding, deps[9], visibility) : null;
d10 = length > 10 ? this._getByDependency(binding, deps[10], visibility) : null;
d11 = length > 11 ? this._getByDependency(binding, deps[11], visibility) : null;
d12 = length > 12 ? this._getByDependency(binding, deps[12], visibility) : null;
d13 = length > 13 ? this._getByDependency(binding, deps[13], visibility) : null;
d14 = length > 14 ? this._getByDependency(binding, deps[14], visibility) : null;
d15 = length > 15 ? this._getByDependency(binding, deps[15], visibility) : null;
d16 = length > 16 ? this._getByDependency(binding, deps[16], visibility) : null;
d17 = length > 17 ? this._getByDependency(binding, deps[17], visibility) : null;
d18 = length > 18 ? this._getByDependency(binding, deps[18], visibility) : null;
d19 = length > 19 ? this._getByDependency(binding, deps[19], visibility) : null;
d0 = length > 0 ? this._getByDependency(provider, deps[0], visibility) : null;
d1 = length > 1 ? this._getByDependency(provider, deps[1], visibility) : null;
d2 = length > 2 ? this._getByDependency(provider, deps[2], visibility) : null;
d3 = length > 3 ? this._getByDependency(provider, deps[3], visibility) : null;
d4 = length > 4 ? this._getByDependency(provider, deps[4], visibility) : null;
d5 = length > 5 ? this._getByDependency(provider, deps[5], visibility) : null;
d6 = length > 6 ? this._getByDependency(provider, deps[6], visibility) : null;
d7 = length > 7 ? this._getByDependency(provider, deps[7], visibility) : null;
d8 = length > 8 ? this._getByDependency(provider, deps[8], visibility) : null;
d9 = length > 9 ? this._getByDependency(provider, deps[9], visibility) : null;
d10 = length > 10 ? this._getByDependency(provider, deps[10], visibility) : null;
d11 = length > 11 ? this._getByDependency(provider, deps[11], visibility) : null;
d12 = length > 12 ? this._getByDependency(provider, deps[12], visibility) : null;
d13 = length > 13 ? this._getByDependency(provider, deps[13], visibility) : null;
d14 = length > 14 ? this._getByDependency(provider, deps[14], visibility) : null;
d15 = length > 15 ? this._getByDependency(provider, deps[15], visibility) : null;
d16 = length > 16 ? this._getByDependency(provider, deps[16], visibility) : null;
d17 = length > 17 ? this._getByDependency(provider, deps[17], visibility) : null;
d18 = length > 18 ? this._getByDependency(provider, deps[18], visibility) : null;
d19 = length > 19 ? this._getByDependency(provider, deps[19], visibility) : null;
} catch (e) {
if (e instanceof AbstractBindingError || e instanceof InstantiationError) {
e.addKey(this, binding.key);
if (e instanceof AbstractProviderError || e instanceof InstantiationError) {
e.addKey(this, provider.key);
}
throw e;
}
@ -874,38 +880,38 @@ export class Injector {
break;
}
} catch (e) {
throw new InstantiationError(this, e, e.stack, binding.key);
throw new InstantiationError(this, e, e.stack, provider.key);
}
return obj;
}
private _getByDependency(binding: ResolvedBinding, dep: Dependency,
bindingVisibility: Visibility): any {
private _getByDependency(provider: ResolvedProvider, dep: Dependency,
providerVisibility: Visibility): any {
var special = isPresent(this._depProvider) ?
this._depProvider.getDependency(this, binding, dep) :
this._depProvider.getDependency(this, provider, dep) :
UNDEFINED;
if (special !== UNDEFINED) {
return special;
} else {
return this._getByKey(dep.key, dep.lowerBoundVisibility, dep.upperBoundVisibility,
dep.optional, bindingVisibility);
dep.optional, providerVisibility);
}
}
private _getByKey(key: Key, lowerBoundVisibility: Object, upperBoundVisibility: Object,
optional: boolean, bindingVisibility: Visibility): any {
optional: boolean, providerVisibility: Visibility): any {
if (key === INJECTOR_KEY) {
return this;
}
if (upperBoundVisibility instanceof SelfMetadata) {
return this._getByKeySelf(key, optional, bindingVisibility);
return this._getByKeySelf(key, optional, providerVisibility);
} else if (upperBoundVisibility instanceof HostMetadata) {
return this._getByKeyHost(key, optional, bindingVisibility, lowerBoundVisibility);
return this._getByKeyHost(key, optional, providerVisibility, lowerBoundVisibility);
} else {
return this._getByKeyDefault(key, optional, bindingVisibility, lowerBoundVisibility);
return this._getByKeyDefault(key, optional, providerVisibility, lowerBoundVisibility);
}
}
@ -914,18 +920,18 @@ export class Injector {
if (optional) {
return null;
} else {
throw new NoBindingError(this, key);
throw new NoProviderError(this, key);
}
}
/** @internal */
_getByKeySelf(key: Key, optional: boolean, bindingVisibility: Visibility): any {
var obj = this._strategy.getObjByKeyId(key.id, bindingVisibility);
_getByKeySelf(key: Key, optional: boolean, providerVisibility: Visibility): any {
var obj = this._strategy.getObjByKeyId(key.id, providerVisibility);
return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, optional);
}
/** @internal */
_getByKeyHost(key: Key, optional: boolean, bindingVisibility: Visibility,
_getByKeyHost(key: Key, optional: boolean, providerVisibility: Visibility,
lowerBoundVisibility: Object): any {
var inj = this;
@ -938,7 +944,7 @@ export class Injector {
}
while (inj != null) {
var obj = inj._strategy.getObjByKeyId(key.id, bindingVisibility);
var obj = inj._strategy.getObjByKeyId(key.id, providerVisibility);
if (obj !== UNDEFINED) return obj;
if (isPresent(inj._parent) && inj._isHost) {
@ -958,20 +964,20 @@ export class Injector {
}
/** @internal */
_getByKeyDefault(key: Key, optional: boolean, bindingVisibility: Visibility,
_getByKeyDefault(key: Key, optional: boolean, providerVisibility: Visibility,
lowerBoundVisibility: Object): any {
var inj = this;
if (lowerBoundVisibility instanceof SkipSelfMetadata) {
bindingVisibility = inj._isHost ? Visibility.PublicAndPrivate : Visibility.Public;
providerVisibility = inj._isHost ? Visibility.PublicAndPrivate : Visibility.Public;
inj = inj._parent;
}
while (inj != null) {
var obj = inj._strategy.getObjByKeyId(key.id, bindingVisibility);
var obj = inj._strategy.getObjByKeyId(key.id, providerVisibility);
if (obj !== UNDEFINED) return obj;
bindingVisibility = inj._isHost ? Visibility.PublicAndPrivate : Visibility.Public;
providerVisibility = inj._isHost ? Visibility.PublicAndPrivate : Visibility.Public;
inj = inj._parent;
}
@ -979,7 +985,7 @@ export class Injector {
}
get displayName(): string {
return `Injector(bindings: [${_mapBindings(this, b => ` "${b.key.displayName}" `).join(", ")}])`;
return `Injector(providers: [${_mapProviders(this, b => ` "${b.key.displayName}" `).join(", ")}])`;
}
toString(): string { return this.displayName; }
@ -988,10 +994,10 @@ export class Injector {
var INJECTOR_KEY = Key.get(Injector);
function _mapBindings(injector: Injector, fn: Function): any[] {
function _mapProviders(injector: Injector, fn: Function): any[] {
var res = [];
for (var i = 0; i < injector._proto.numberOfBindings; ++i) {
res.push(fn(injector._proto.getBindingAtIndex(i)));
for (var i = 0; i < injector._proto.numberOfProviders; ++i) {
res.push(fn(injector._proto.getProviderAtIndex(i)));
}
return res;
}

View File

@ -16,7 +16,7 @@ export {TypeLiteral} from './type_literal';
* injector to store created objects in a more efficient way.
*
* `Key` should not be created directly. {@link Injector} creates keys automatically when resolving
* bindings.
* providers.
*/
export class Key {
/**

View File

@ -17,7 +17,7 @@ import {CONST, CONST_EXPR, stringify, isBlank, isPresent} from "angular2/src/cor
* }
*
* var injector = Injector.resolveAndCreate([
* bind("MyEngine").toClass(Engine),
* provide("MyEngine", {asClass: Engine}),
* Car
* ]);
*
@ -212,7 +212,7 @@ export class SkipSelfMetadata {
*
* @Component({
* selector: 'parent-cmp',
* bindings: [HostService]
* providers: [HostService]
* })
* @View({
* template: `
@ -225,7 +225,7 @@ export class SkipSelfMetadata {
*
* @Component({
* selector: 'app',
* bindings: [OtherService]
* providers: [OtherService]
* })
* @View({
* template: `

View File

@ -1,22 +1,22 @@
import {CONST} from 'angular2/src/core/facade/lang';
/**
* Creates a token that can be used in a DI Binding.
* Creates a token that can be used in a DI Provider.
*
* ### Example ([live demo](http://plnkr.co/edit/Ys9ezXpj2Mnoy3Uc8KBp?p=preview))
*
* ```typescript
* var t = new OpaqueToken("binding");
* var t = new OpaqueToken("value");
*
* var injector = Injector.resolveAndCreate([
* bind(t).toValue("bindingValue")
* provide(t, {asValue: "providedValue"})
* ]);
*
* expect(injector.get(t)).toEqual("bindingValue");
* ```
*
* Using an `OpaqueToken` is preferable to using strings as tokens because of possible collisions
* caused by multiple bindings using the same string as two different tokens.
* caused by multiple providers using the same string as two different tokens.
*
* Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better
* error messages.

View File

@ -25,8 +25,8 @@ import {
} from './metadata';
import {
NoAnnotationError,
MixingMultiBindingsWithRegularBindings,
InvalidBindingError
MixingMultiProvidersWithRegularProvidersError,
InvalidProviderError
} from './exceptions';
import {resolveForwardRef} from './forward_ref';
@ -42,22 +42,22 @@ const _EMPTY_LIST = CONST_EXPR([]);
/**
* Describes how the {@link Injector} should instantiate a given token.
*
* See {@link bind}.
* See {@link provide}.
*
* ### Example ([live demo](http://plnkr.co/edit/GNAyj6K6PfYg2NBzgwZ5?p%3Dpreview&p=preview))
*
* ```javascript
* var injector = Injector.resolveAndCreate([
* new Binding("message", { toValue: 'Hello' })
* new Provider("message", { toValue: 'Hello' })
* ]);
*
* expect(injector.get("message")).toEqual('Hello');
* ```
*/
@CONST()
export class Binding {
export class Provider {
/**
* Token used when retrieving this binding. Usually, it is a type {@link `Type`}.
* Token used when retrieving this provider. Usually, it is a type {@link `Type`}.
*/
token;
@ -77,11 +77,11 @@ export class Binding {
*
* var injectorClass = Injector.resolveAndCreate([
* Car,
* new Binding(Vehicle, { toClass: Car })
* new Provider(Vehicle, { toClass: Car })
* ]);
* var injectorAlias = Injector.resolveAndCreate([
* Car,
* new Binding(Vehicle, { toAlias: Car })
* new Provider(Vehicle, { toAlias: Car })
* ]);
*
* expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
@ -100,7 +100,7 @@ export class Binding {
*
* ```javascript
* var injector = Injector.resolveAndCreate([
* new Binding("message", { toValue: 'Hello' })
* new Provider("message", { toValue: 'Hello' })
* ]);
*
* expect(injector.get("message")).toEqual('Hello');
@ -126,11 +126,11 @@ export class Binding {
*
* var injectorAlias = Injector.resolveAndCreate([
* Car,
* new Binding(Vehicle, { toAlias: Car })
* new Provider(Vehicle, { toAlias: Car })
* ]);
* var injectorClass = Injector.resolveAndCreate([
* Car,
* new Binding(Vehicle, { toClass: Car })
* new Provider(Vehicle, { toClass: Car })
* ]);
*
* expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
@ -149,8 +149,8 @@ export class Binding {
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* new Binding(Number, { toFactory: () => { return 1+2; }}),
* new Binding(String, { toFactory: (value) => { return "Value: " + value; },
* new Provider(Number, { toFactory: () => { return 1+2; }}),
* new Provider(String, { toFactory: (value) => { return "Value: " + value; },
* deps: [Number] })
* ]);
*
@ -170,8 +170,8 @@ export class Binding {
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* new Binding(Number, { toFactory: () => { return 1+2; }}),
* new Binding(String, { toFactory: (value) => { return "Value: " + value; },
* new Provider(Number, { toFactory: () => { return 1+2; }}),
* new Provider(String, { toFactory: (value) => { return "Value: " + value; },
* deps: [Number] })
* ]);
*
@ -205,40 +205,63 @@ export class Binding {
// TODO: Provide a full working example after alpha38 is released.
/**
* Creates multiple bindings matching the same token (a multi-binding).
* Creates multiple providers matching the same token (a multi-provider).
*
* Multi-bindings are used for creating pluggable service, where the system comes
* with some default bindings, and the user can register additonal bindings.
* The combination of the default bindings and the additional bindings will be
* Multi-providers are used for creating pluggable service, where the system comes
* with some default providers, and the user can register additonal providers.
* The combination of the default providers and the additional providers will be
* used to drive the behavior of the system.
*
* ### Example
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* new Binding("Strings", { toValue: "String1", multi: true}),
* new Binding("Strings", { toValue: "String2", multi: true})
* new Provider("Strings", { toValue: "String1", multi: true}),
* new Provider("Strings", { toValue: "String2", multi: true})
* ]);
*
* expect(injector.get("Strings")).toEqual(["String1", "String2"]);
* ```
*
* Multi-bindings and regular bindings cannot be mixed. The following
* Multi-providers and regular providers cannot be mixed. The following
* will throw an exception:
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* new Binding("Strings", { toValue: "String1", multi: true }),
* new Binding("Strings", { toValue: "String2"})
* new Provider("Strings", { toValue: "String1", multi: true }),
* new Provider("Strings", { toValue: "String2"})
* ]);
* ```
*/
get multi(): boolean { return normalizeBool(this._multi); }
}
/**
* @deprecated
*/
@CONST()
export class Binding extends Provider {
constructor(token, {toClass, toValue, toAlias, toFactory, deps, multi}: {
toClass?: Type,
toValue?: any,
toAlias?: any,
toFactory?: Function,
deps?: Object[],
multi?: boolean
}) {
super(token, {
toClass: toClass,
toValue: toValue,
toAlias: toAlias,
toFactory: toFactory,
deps: deps,
multi: multi
});
}
}
/**
* An internal resolved representation of a {@link Binding} used by the {@link Injector}.
* An internal resolved representation of a {@link Provider} used by the {@link Injector}.
*
* It is usually created automatically by `Injector.resolveAndCreate`.
*
@ -247,13 +270,13 @@ export class Binding {
* ### Example ([live demo](http://plnkr.co/edit/RfEnhh8kUEI0G3qsnIeT?p%3Dpreview&p=preview))
*
* ```typescript
* var resolvedBindings = Injector.resolve([new Binding('message', {toValue: 'Hello'})]);
* var injector = Injector.fromResolvedBindings(resolvedBindings);
* var resolvedProviders = Injector.resolve([new Provider('message', {toValue: 'Hello'})]);
* var injector = Injector.fromResolvedProviders(resolvedProviders);
*
* expect(injector.get('message')).toEqual('Hello');
* ```
*/
export interface ResolvedBinding {
export interface ResolvedProvider {
/**
* A key, usually a `Type`.
*/
@ -265,20 +288,25 @@ export interface ResolvedBinding {
resolvedFactories: ResolvedFactory[];
/**
* Indicates if the binding is a multi-binding or a regular binding.
* Indicates if the provider is a multi-provider or a regular provider.
*/
multiBinding: boolean;
multiProvider: boolean;
}
export class ResolvedBinding_ implements ResolvedBinding {
/**
* @deprecated
*/
export interface ResolvedBinding extends ResolvedProvider {}
export class ResolvedProvider_ implements ResolvedBinding {
constructor(public key: Key, public resolvedFactories: ResolvedFactory[],
public multiBinding: boolean) {}
public multiProvider: boolean) {}
get resolvedFactory(): ResolvedFactory { return this.resolvedFactories[0]; }
}
/**
* An internal resolved representation of a factory function created by resolving {@link Binding}.
* An internal resolved representation of a factory function created by resolving {@link Provider}.
*/
export class ResolvedFactory {
constructor(
@ -294,22 +322,49 @@ export class ResolvedFactory {
}
/**
* Creates a {@link Binding}.
* @deprecated
* Creates a {@link Provider}.
*
* To construct a {@link Binding}, bind a `token` to either a class, a value, a factory function, or
* To construct a {@link Provider}, bind a `token` to either a class, a value, a factory function,
* or
* to an alias to another `token`.
* See {@link BindingBuilder} for more details.
* See {@link ProviderBuilder} for more details.
*
* The `token` is most commonly a class or {@link angular2/di/OpaqueToken}.
*/
export function bind(token): BindingBuilder {
return new BindingBuilder(token);
export function bind(token): ProviderBuilder {
return new ProviderBuilder(token);
}
/**
* Creates a {@link Provider}.
*
* See {@link Provider} for more details.
*
* <!-- TODO: improve the docs -->
*/
export function provide(token, {asClass, asValue, asAlias, asFactory, deps, multi}: {
asClass?: Type,
asValue?: any,
asAlias?: any,
asFactory?: Function,
deps?: Object[],
multi?: boolean
}): Provider {
return new Provider(token, {
toClass: asClass,
toValue: asValue,
toAlias: asAlias,
toFactory: asFactory,
deps: deps,
multi: multi
});
}
/**
* Helper class for the {@link bind} function.
*/
export class BindingBuilder {
export class ProviderBuilder {
constructor(public token) {}
/**
@ -327,11 +382,11 @@ export class BindingBuilder {
*
* var injectorClass = Injector.resolveAndCreate([
* Car,
* bind(Vehicle).toClass(Car)
* provide(Vehicle, {asClass: Car})
* ]);
* var injectorAlias = Injector.resolveAndCreate([
* Car,
* bind(Vehicle).toAlias(Car)
* provide(Vehicle, {asAlias: Car})
* ]);
*
* expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
@ -341,12 +396,12 @@ export class BindingBuilder {
* expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
* ```
*/
toClass(type: Type): Binding {
toClass(type: Type): Provider {
if (!isType(type)) {
throw new BaseException(
`Trying to create a class binding but "${stringify(type)}" is not a class!`);
`Trying to create a class provider but "${stringify(type)}" is not a class!`);
}
return new Binding(this.token, {toClass: type});
return new Provider(this.token, {toClass: type});
}
/**
@ -356,13 +411,13 @@ export class BindingBuilder {
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* bind('message').toValue('Hello')
* provide('message', {asValue: 'Hello'})
* ]);
*
* expect(injector.get('message')).toEqual('Hello');
* ```
*/
toValue(value: any): Binding { return new Binding(this.token, {toValue: value}); }
toValue(value: any): Provider { return new Provider(this.token, {toValue: value}); }
/**
* Binds a DI token as an alias for an existing token.
@ -383,11 +438,11 @@ export class BindingBuilder {
*
* var injectorAlias = Injector.resolveAndCreate([
* Car,
* bind(Vehicle).toAlias(Car)
* provide(Vehicle, {asAlias: Car})
* ]);
* var injectorClass = Injector.resolveAndCreate([
* Car,
* bind(Vehicle).toClass(Car)
* provide(Vehicle, {asClass: Car})
* ]);
*
* expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
@ -397,11 +452,11 @@ export class BindingBuilder {
* expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
* ```
*/
toAlias(aliasToken: /*Type*/ any): Binding {
toAlias(aliasToken: /*Type*/ any): Provider {
if (isBlank(aliasToken)) {
throw new BaseException(`Can not alias ${stringify(this.token)} to a blank value!`);
}
return new Binding(this.token, {toAlias: aliasToken});
return new Provider(this.token, {toAlias: aliasToken});
}
/**
@ -411,69 +466,69 @@ export class BindingBuilder {
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* bind(Number).toFactory(() => { return 1+2; }),
* bind(String).toFactory((v) => { return "Value: " + v; }, [Number])
* provide(Number, {asFactory: () => { return 1+2; }}),
* provide(String, {asFactory: (v) => { return "Value: " + v; }, deps: [Number]})
* ]);
*
* expect(injector.get(Number)).toEqual(3);
* expect(injector.get(String)).toEqual('Value: 3');
* ```
*/
toFactory(factory: Function, dependencies?: any[]): Binding {
toFactory(factory: Function, dependencies?: any[]): Provider {
if (!isFunction(factory)) {
throw new BaseException(
`Trying to create a factory binding but "${stringify(factory)}" is not a function!`);
`Trying to create a factory provider but "${stringify(factory)}" is not a function!`);
}
return new Binding(this.token, {toFactory: factory, deps: dependencies});
return new Provider(this.token, {toFactory: factory, deps: dependencies});
}
}
/**
* Resolve a single binding.
* Resolve a single provider.
*/
export function resolveFactory(binding: Binding): ResolvedFactory {
export function resolveFactory(provider: Provider): ResolvedFactory {
var factoryFn: Function;
var resolvedDeps;
if (isPresent(binding.toClass)) {
var toClass = resolveForwardRef(binding.toClass);
if (isPresent(provider.toClass)) {
var toClass = resolveForwardRef(provider.toClass);
factoryFn = reflector.factory(toClass);
resolvedDeps = _dependenciesFor(toClass);
} else if (isPresent(binding.toAlias)) {
} else if (isPresent(provider.toAlias)) {
factoryFn = (aliasInstance) => aliasInstance;
resolvedDeps = [Dependency.fromKey(Key.get(binding.toAlias))];
} else if (isPresent(binding.toFactory)) {
factoryFn = binding.toFactory;
resolvedDeps = _constructDependencies(binding.toFactory, binding.dependencies);
resolvedDeps = [Dependency.fromKey(Key.get(provider.toAlias))];
} else if (isPresent(provider.toFactory)) {
factoryFn = provider.toFactory;
resolvedDeps = _constructDependencies(provider.toFactory, provider.dependencies);
} else {
factoryFn = () => binding.toValue;
factoryFn = () => provider.toValue;
resolvedDeps = _EMPTY_LIST;
}
return new ResolvedFactory(factoryFn, resolvedDeps);
}
/**
* Converts the {@link Binding} into {@link ResolvedBinding}.
* Converts the {@link Provider} into {@link ResolvedProvider}.
*
* {@link Injector} internally only uses {@link ResolvedBinding}, {@link Binding} contains
* convenience binding syntax.
* {@link Injector} internally only uses {@link ResolvedProvider}, {@link Provider} contains
* convenience provider syntax.
*/
export function resolveBinding(binding: Binding): ResolvedBinding {
return new ResolvedBinding_(Key.get(binding.token), [resolveFactory(binding)], false);
export function resolveProvider(provider: Provider): ResolvedProvider {
return new ResolvedProvider_(Key.get(provider.token), [resolveFactory(provider)], false);
}
/**
* Resolve a list of Bindings.
* Resolve a list of Providers.
*/
export function resolveBindings(bindings: Array<Type | Binding | any[]>): ResolvedBinding[] {
var normalized = _createListOfBindings(
_normalizeBindings(bindings, new Map<number, _NormalizedBinding | _NormalizedBinding[]>()));
export function resolveProviders(providers: Array<Type | Provider | any[]>): ResolvedProvider[] {
var normalized = _createListOfProviders(_normalizeProviders(
providers, new Map<number, _NormalizedProvider | _NormalizedProvider[]>()));
return normalized.map(b => {
if (b instanceof _NormalizedBinding) {
return new ResolvedBinding_(b.key, [b.resolvedFactory], false);
if (b instanceof _NormalizedProvider) {
return new ResolvedProvider_(b.key, [b.resolvedFactory], false);
} else {
var arr = <_NormalizedBinding[]>b;
return new ResolvedBinding_(arr[0].key, arr.map(_ => _.resolvedFactory), true);
var arr = <_NormalizedProvider[]>b;
return new ResolvedProvider_(arr[0].key, arr.map(_ => _.resolvedFactory), true);
}
});
}
@ -481,66 +536,66 @@ export function resolveBindings(bindings: Array<Type | Binding | any[]>): Resolv
/**
* The algorithm works as follows:
*
* [Binding] -> [_NormalizedBinding|[_NormalizedBinding]] -> [ResolvedBinding]
* [Provider] -> [_NormalizedProvider|[_NormalizedProvider]] -> [ResolvedProvider]
*
* _NormalizedBinding is essentially a resolved binding before it was grouped by key.
* _NormalizedProvider is essentially a resolved provider before it was grouped by key.
*/
class _NormalizedBinding {
class _NormalizedProvider {
constructor(public key: Key, public resolvedFactory: ResolvedFactory) {}
}
function _createListOfBindings(flattenedBindings: Map<number, any>): any[] {
return MapWrapper.values(flattenedBindings);
function _createListOfProviders(flattenedProviders: Map<number, any>): any[] {
return MapWrapper.values(flattenedProviders);
}
function _normalizeBindings(bindings: Array<Type | Binding | BindingBuilder | any[]>,
res: Map<number, _NormalizedBinding | _NormalizedBinding[]>):
Map<number, _NormalizedBinding | _NormalizedBinding[]> {
bindings.forEach(b => {
function _normalizeProviders(providers: Array<Type | Provider | ProviderBuilder | any[]>,
res: Map<number, _NormalizedProvider | _NormalizedProvider[]>):
Map<number, _NormalizedProvider | _NormalizedProvider[]> {
providers.forEach(b => {
if (b instanceof Type) {
_normalizeBinding(bind(b).toClass(b), res);
_normalizeProvider(provide(b, {asClass: b}), res);
} else if (b instanceof Binding) {
_normalizeBinding(b, res);
} else if (b instanceof Provider) {
_normalizeProvider(b, res);
} else if (b instanceof Array) {
_normalizeBindings(b, res);
_normalizeProviders(b, res);
} else if (b instanceof BindingBuilder) {
throw new InvalidBindingError(b.token);
} else if (b instanceof ProviderBuilder) {
throw new InvalidProviderError(b.token);
} else {
throw new InvalidBindingError(b);
throw new InvalidProviderError(b);
}
});
return res;
}
function _normalizeBinding(b: Binding, res: Map<number, _NormalizedBinding | _NormalizedBinding[]>):
void {
function _normalizeProvider(b: Provider,
res: Map<number, _NormalizedProvider | _NormalizedProvider[]>): void {
var key = Key.get(b.token);
var factory = resolveFactory(b);
var normalized = new _NormalizedBinding(key, factory);
var normalized = new _NormalizedProvider(key, factory);
if (b.multi) {
var existingBinding = res.get(key.id);
var existingProvider = res.get(key.id);
if (existingBinding instanceof Array) {
existingBinding.push(normalized);
if (existingProvider instanceof Array) {
existingProvider.push(normalized);
} else if (isBlank(existingBinding)) {
} else if (isBlank(existingProvider)) {
res.set(key.id, [normalized]);
} else {
throw new MixingMultiBindingsWithRegularBindings(existingBinding, b);
throw new MixingMultiProvidersWithRegularProvidersError(existingProvider, b);
}
} else {
var existingBinding = res.get(key.id);
var existingProvider = res.get(key.id);
if (existingBinding instanceof Array) {
throw new MixingMultiBindingsWithRegularBindings(existingBinding, b);
if (existingProvider instanceof Array) {
throw new MixingMultiProvidersWithRegularProvidersError(existingProvider, b);
}
res.set(key.id, normalized);

View File

@ -27,7 +27,7 @@ class _ArrayLogger {
* }
* }
*
* bootstrap(MyApp, [bind(ExceptionHandler).toClass(MyExceptionHandler)])
* bootstrap(MyApp, [provide(ExceptionHandler, {asClass: MyExceptionHandler})])
*
* ```
*/

View File

@ -41,12 +41,17 @@ import {FormBuilder} from './forms/form_builder';
import {CONST_EXPR, Type} from './facade/lang';
/**
* Shorthand set of bindings used for building Angular forms.
* Shorthand set of providers used for building Angular forms.
*
* ### Example:
*
* ```typescript
* bootstrap(MyApp, [FORM_BINDINGS]);
* bootstrap(MyApp, [FORM_PROVIDERS]);
* ```
*/
export const FORM_BINDINGS: Type[] = CONST_EXPR([FormBuilder]);
export const FORM_PROVIDERS: Type[] = CONST_EXPR([FormBuilder]);
/**
* @deprecated
*/
export const FORM_BINDINGS = FORM_PROVIDERS;

View File

@ -1,13 +1,13 @@
import {Directive} from 'angular2/src/core/metadata';
import {Renderer} from 'angular2/src/core/render';
import {ElementRef} from 'angular2/src/core/linker';
import {Self, forwardRef, Binding} from 'angular2/src/core/di';
import {Self, forwardRef, Provider} from 'angular2/src/core/di';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
import {setProperty} from './shared';
const CHECKBOX_VALUE_ACCESSOR = CONST_EXPR(new Binding(
const CHECKBOX_VALUE_ACCESSOR = CONST_EXPR(new Provider(
NG_VALUE_ACCESSOR, {toAlias: forwardRef(() => CheckboxControlValueAccessor), multi: true}));
/**

View File

@ -1,13 +1,13 @@
import {Directive} from 'angular2/src/core/metadata';
import {ElementRef} from 'angular2/src/core/linker';
import {Renderer} from 'angular2/src/core/render';
import {Self, forwardRef, Binding} from 'angular2/src/core/di';
import {Self, forwardRef, Provider} from 'angular2/src/core/di';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
import {isBlank, CONST_EXPR} from 'angular2/src/core/facade/lang';
import {setProperty} from './shared';
const DEFAULT_VALUE_ACCESSOR = CONST_EXPR(
new Binding(NG_VALUE_ACCESSOR, {toAlias: forwardRef(() => DefaultValueAccessor), multi: true}));
const DEFAULT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
NG_VALUE_ACCESSOR, {toAlias: forwardRef(() => DefaultValueAccessor), multi: true}));
/**
* The default accessor for writing a value and listening to changes that is used by the

View File

@ -1,6 +1,6 @@
import {OnInit, OnDestroy} from 'angular2/lifecycle_hooks';
import {Directive} from 'angular2/src/core/metadata';
import {Inject, Host, SkipSelf, forwardRef, Binding} from 'angular2/src/core/di';
import {Inject, Host, SkipSelf, forwardRef, Provider} from 'angular2/src/core/di';
import {ListWrapper} from 'angular2/src/core/facade/collection';
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
@ -10,7 +10,7 @@ import {ControlGroup} from '../model';
import {Form} from './form_interface';
const controlGroupBinding =
CONST_EXPR(new Binding(ControlContainer, {toAlias: forwardRef(() => NgControlGroup)}));
CONST_EXPR(new Provider(ControlContainer, {toAlias: forwardRef(() => NgControlGroup)}));
/**
* Creates and binds a control group to a DOM element.

View File

@ -3,7 +3,7 @@ import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
import {OnChanges, OnDestroy} from 'angular2/lifecycle_hooks';
import {SimpleChange} from 'angular2/src/core/change_detection';
import {Query, Directive} from 'angular2/src/core/metadata';
import {forwardRef, Host, SkipSelf, Binding, Inject, Optional} from 'angular2/src/core/di';
import {forwardRef, Host, SkipSelf, Provider, Inject, Optional} from 'angular2/src/core/di';
import {ControlContainer} from './control_container';
import {NgControl} from './ng_control';
@ -14,7 +14,7 @@ import {Validators, NG_VALIDATORS} from '../validators';
const controlNameBinding =
CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgControlName)}));
CONST_EXPR(new Provider(NgControl, {toAlias: forwardRef(() => NgControlName)}));
/**
* Creates and binds a control with a specified name to a DOM element.

View File

@ -7,7 +7,7 @@ import {
import {StringMapWrapper, ListWrapper} from 'angular2/src/core/facade/collection';
import {isPresent, isBlank, CONST_EXPR} from 'angular2/src/core/facade/lang';
import {Directive} from 'angular2/src/core/metadata';
import {forwardRef, Binding} from 'angular2/src/core/di';
import {forwardRef, Provider} from 'angular2/src/core/di';
import {NgControl} from './ng_control';
import {Form} from './form_interface';
import {NgControlGroup} from './ng_control_group';
@ -15,8 +15,8 @@ import {ControlContainer} from './control_container';
import {AbstractControl, ControlGroup, Control} from '../model';
import {setUpControl} from './shared';
const formDirectiveBinding =
CONST_EXPR(new Binding(ControlContainer, {toAlias: forwardRef(() => NgForm)}));
const formDirectiveProvider =
CONST_EXPR(new Provider(ControlContainer, {toAlias: forwardRef(() => NgForm)}));
/**
* If `NgForm` is bound in a component, `<form>` elements in that component will be
@ -81,7 +81,7 @@ const formDirectiveBinding =
*/
@Directive({
selector: 'form:not([ng-no-form]):not([ng-form-model]),ng-form,[ng-form]',
bindings: [formDirectiveBinding],
bindings: [formDirectiveProvider],
host: {
'(submit)': 'onSubmit()',
},

View File

@ -3,7 +3,7 @@ import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
import {OnChanges} from 'angular2/lifecycle_hooks';
import {SimpleChange} from 'angular2/src/core/change_detection';
import {Query, Directive} from 'angular2/src/core/metadata';
import {forwardRef, Binding, Inject, Optional} from 'angular2/src/core/di';
import {forwardRef, Provider, Inject, Optional} from 'angular2/src/core/di';
import {NgControl} from './ng_control';
import {Control} from '../model';
import {Validators, NG_VALIDATORS} from '../validators';
@ -11,7 +11,7 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor'
import {setUpControl, isPropertyUpdated, selectValueAccessor} from './shared';
const formControlBinding =
CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgFormControl)}));
CONST_EXPR(new Provider(NgControl, {toAlias: forwardRef(() => NgFormControl)}));
/**
* Binds an existing {@link Control} to a DOM element.

View File

@ -4,7 +4,7 @@ import {ObservableWrapper, EventEmitter} from 'angular2/src/core/facade/async';
import {OnChanges} from 'angular2/lifecycle_hooks';
import {Directive} from 'angular2/src/core/metadata';
import {forwardRef, Binding} from 'angular2/src/core/di';
import {forwardRef, Provider} from 'angular2/src/core/di';
import {NgControl} from './ng_control';
import {NgControlGroup} from './ng_control_group';
import {ControlContainer} from './control_container';
@ -12,8 +12,8 @@ import {Form} from './form_interface';
import {Control, ControlGroup} from '../model';
import {setUpControl} from './shared';
const formDirectiveBinding =
CONST_EXPR(new Binding(ControlContainer, {toAlias: forwardRef(() => NgFormModel)}));
const formDirectiveProvider =
CONST_EXPR(new Provider(ControlContainer, {toAlias: forwardRef(() => NgFormModel)}));
/**
* Binds an existing control group to a DOM element.
@ -91,7 +91,7 @@ const formDirectiveBinding =
*/
@Directive({
selector: '[ng-form-model]',
bindings: [formDirectiveBinding],
bindings: [formDirectiveProvider],
inputs: ['form: ng-form-model'],
host: {'(submit)': 'onSubmit()'},
outputs: ['ngSubmit'],

View File

@ -3,14 +3,15 @@ import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
import {OnChanges} from 'angular2/lifecycle_hooks';
import {SimpleChange} from 'angular2/src/core/change_detection';
import {Query, Directive} from 'angular2/src/core/metadata';
import {forwardRef, Binding, Inject, Optional} from 'angular2/src/core/di';
import {forwardRef, Provider, Inject, Optional} from 'angular2/src/core/di';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
import {NgControl} from './ng_control';
import {Control} from '../model';
import {Validators, NG_VALIDATORS} from '../validators';
import {setUpControl, isPropertyUpdated, selectValueAccessor} from './shared';
const formControlBinding = CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgModel)}));
const formControlBinding =
CONST_EXPR(new Provider(NgControl, {toAlias: forwardRef(() => NgModel)}));
/**
* Binds a domain model to a form control.

View File

@ -1,4 +1,4 @@
import {Self, forwardRef, Binding} from 'angular2/src/core/di';
import {Self, forwardRef, Provider} from 'angular2/src/core/di';
import {Renderer} from 'angular2/src/core/render';
import {ElementRef, QueryList} from 'angular2/src/core/linker';
import {Query, Directive} from 'angular2/src/core/metadata';
@ -8,7 +8,7 @@ import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor'
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
import {setProperty} from './shared';
const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Binding(
const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
NG_VALUE_ACCESSOR, {toAlias: forwardRef(() => SelectControlValueAccessor), multi: true}));
/**

View File

@ -1,10 +1,10 @@
import {forwardRef, Binding, OpaqueToken} from 'angular2/src/core/di';
import {forwardRef, Provider, OpaqueToken} from 'angular2/src/core/di';
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
import {Directive} from 'angular2/src/core/metadata';
import {Validators, NG_VALIDATORS} from '../validators';
const DEFAULT_VALIDATORS =
CONST_EXPR(new Binding(NG_VALIDATORS, {toValue: Validators.required, multi: true}));
CONST_EXPR(new Provider(NG_VALIDATORS, {toValue: Validators.required, multi: true}));
@Directive({
selector: '[required][ng-control],[required][ng-form-control],[required][ng-model]',

View File

@ -15,7 +15,7 @@ import * as modelModule from './model';
*
* @Component({
* selector: 'login-comp',
* viewBindings: [FormBuilder]
* viewProviders: [FormBuilder]
* })
* @View({
* template: `

View File

@ -108,22 +108,18 @@ export class DirectiveResolver {
var mergedQueries =
isPresent(dm.queries) ? StringMapWrapper.merge(dm.queries, queries) : queries;
// TODO: remove after migrating from properties to inputs
if (mergedInputs.length == 0 && isPresent(dm.properties)) mergedInputs = dm.properties;
if (mergedOutputs.length == 0 && isPresent(dm.events)) mergedOutputs = dm.events;
if (dm instanceof ComponentMetadata) {
return new ComponentMetadata({
selector: dm.selector,
inputs: mergedInputs,
outputs: mergedOutputs,
host: mergedHost,
bindings: dm.bindings,
exportAs: dm.exportAs,
moduleId: dm.moduleId,
queries: mergedQueries,
changeDetection: dm.changeDetection,
viewBindings: dm.viewBindings
providers: dm.providers,
viewProviders: dm.viewProviders
});
} else {
@ -132,10 +128,10 @@ export class DirectiveResolver {
inputs: mergedInputs,
outputs: mergedOutputs,
host: mergedHost,
bindings: dm.bindings,
exportAs: dm.exportAs,
moduleId: dm.moduleId,
queries: mergedQueries
queries: mergedQueries,
providers: dm.providers
});
}
}

View File

@ -1,4 +1,4 @@
import {Key, Injector, ResolvedBinding, Binding, bind, Injectable} from 'angular2/src/core/di';
import {Key, Injector, ResolvedProvider, Provider, provide, Injectable} from 'angular2/src/core/di';
import {Compiler} from './compiler';
import {isType, Type, stringify, isPresent} from 'angular2/src/core/facade/lang';
import {Promise} from 'angular2/src/core/facade/async';
@ -161,7 +161,7 @@ export abstract class DynamicComponentLoader {
* location within the Component View of this Component Instance is specified via `anchorName`
* Template Variable Name.
*
* You can optionally provide `bindings` to configure the {@link Injector} provisioned for this
* You can optionally provide `providers` to configure the {@link Injector} provisioned for this
* Component Instance.
*
* Returns a promise for the {@link ComponentRef} representing the newly created Component.
@ -209,13 +209,13 @@ export abstract class DynamicComponentLoader {
* ```
*/
abstract loadIntoLocation(type: Type, hostLocation: ElementRef, anchorName: string,
bindings?: ResolvedBinding[]): Promise<ComponentRef>;
providers?: ResolvedProvider[]): Promise<ComponentRef>;
/**
* Creates an instance of a Component and attaches it to the View Container found at the
* `location` specified as {@link ElementRef}.
*
* You can optionally provide `bindings` to configure the {@link Injector} provisioned for this
* You can optionally provide `providers` to configure the {@link Injector} provisioned for this
* Component Instance.
*
* Returns a promise for the {@link ComponentRef} representing the newly created Component.
@ -256,7 +256,7 @@ export abstract class DynamicComponentLoader {
* <child-component>Child</child-component>
* ```
*/
abstract loadNextToLocation(type: Type, location: ElementRef, bindings?: ResolvedBinding[]):
abstract loadNextToLocation(type: Type, location: ElementRef, providers?: ResolvedProvider[]):
Promise<ComponentRef>;
}
@ -283,17 +283,18 @@ export class DynamicComponentLoader_ extends DynamicComponentLoader {
}
loadIntoLocation(type: Type, hostLocation: ElementRef, anchorName: string,
bindings: ResolvedBinding[] = null): Promise<ComponentRef> {
providers: ResolvedProvider[] = null): Promise<ComponentRef> {
return this.loadNextToLocation(
type, this._viewManager.getNamedElementInComponentView(hostLocation, anchorName), bindings);
type, this._viewManager.getNamedElementInComponentView(hostLocation, anchorName),
providers);
}
loadNextToLocation(type: Type, location: ElementRef,
bindings: ResolvedBinding[] = null): Promise<ComponentRef> {
providers: ResolvedProvider[] = null): Promise<ComponentRef> {
return this._compiler.compileInHost(type).then(hostProtoViewRef => {
var viewContainer = this._viewManager.getViewContainer(location);
var hostViewRef =
viewContainer.createHostView(hostProtoViewRef, viewContainer.length, bindings);
viewContainer.createHostView(hostProtoViewRef, viewContainer.length, providers);
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);

View File

@ -1,13 +1,13 @@
import {isBlank} from 'angular2/src/core/facade/lang';
import {BaseException} from 'angular2/src/core/facade/exceptions';
import * as eiModule from './element_injector';
import {DirectiveBinding} from './element_injector';
import {DirectiveProvider} from './element_injector';
import * as viewModule from './view';
export class ElementBinder {
constructor(public index: number, public parent: ElementBinder, public distanceToParent: number,
public protoElementInjector: eiModule.ProtoElementInjector,
public componentDirective: DirectiveBinding,
public componentDirective: DirectiveProvider,
public nestedProtoView: viewModule.AppProtoView) {
if (isBlank(index)) {
throw new BaseException('null index not allowed.');

View File

@ -13,11 +13,11 @@ import {
Injector,
Key,
Dependency,
bind,
Binding,
ResolvedBinding,
NoBindingError,
AbstractBindingError,
provide,
Provider,
ResolvedProvider,
NoProviderError,
AbstractProviderError,
CyclicDependencyError,
resolveForwardRef
} from 'angular2/src/core/di';
@ -27,10 +27,10 @@ import {
Visibility,
InjectorInlineStrategy,
InjectorDynamicStrategy,
BindingWithVisibility,
ProviderWithVisibility,
DependencyProvider
} from 'angular2/src/core/di/injector';
import {resolveBinding, ResolvedFactory, ResolvedBinding_} from 'angular2/src/core/di/binding';
import {resolveProvider, ResolvedFactory, ResolvedProvider_} from 'angular2/src/core/di/provider';
import {AttributeMetadata, QueryMetadata} from '../metadata/di';
@ -49,7 +49,7 @@ import {QueryList} from './query_list';
import {reflector} from 'angular2/src/core/reflection/reflection';
import {SetterFn} from 'angular2/src/core/reflection/types';
import {EventConfig} from 'angular2/src/core/linker/event_config';
import {PipeBinding} from '../pipes/pipe_binding';
import {PipeProvider} from 'angular2/src/core/pipes/pipe_provider';
import {LifecycleHooks} from './interfaces';
import {ViewContainerRef_} from "./view_container_ref";
@ -129,12 +129,12 @@ export class DirectiveDependency extends Dependency {
}
}
export class DirectiveBinding extends ResolvedBinding_ {
export class DirectiveProvider extends ResolvedProvider_ {
public callOnDestroy: boolean;
constructor(key: Key, factory: Function, deps: Dependency[], public metadata: DirectiveMetadata,
public bindings: Array<Type | Binding | any[]>,
public viewBindings: Array<Type | Binding | any[]>) {
public providers: Array<Type | Provider | any[]>,
public viewProviders: Array<Type | Provider | any[]>) {
super(key, [new ResolvedFactory(factory, deps)], false);
this.callOnDestroy = hasLifecycleHook(LifecycleHooks.OnDestroy, key.token);
}
@ -157,24 +157,25 @@ export class DirectiveBinding extends ResolvedBinding_ {
[];
}
static createFromBinding(binding: Binding, meta: DirectiveMetadata): DirectiveBinding {
static createFromProvider(provider: Provider, meta: DirectiveMetadata): DirectiveProvider {
if (isBlank(meta)) {
meta = new DirectiveMetadata();
}
var rb = resolveBinding(binding);
var rb = resolveProvider(provider);
var rf = rb.resolvedFactories[0];
var deps = rf.dependencies.map(DirectiveDependency.createFrom);
var bindings = isPresent(meta.bindings) ? meta.bindings : [];
var viewBindigs =
meta instanceof ComponentMetadata && isPresent(meta.viewBindings) ? meta.viewBindings : [];
return new DirectiveBinding(rb.key, rf.factory, deps, meta, bindings, viewBindigs);
var providers = isPresent(meta.providers) ? meta.providers : [];
var viewBindigs = meta instanceof ComponentMetadata && isPresent(meta.viewProviders) ?
meta.viewProviders :
[];
return new DirectiveProvider(rb.key, rf.factory, deps, meta, providers, viewBindigs);
}
static createFromType(type: Type, annotation: DirectiveMetadata): DirectiveBinding {
var binding = new Binding(type, {toClass: type});
return DirectiveBinding.createFromBinding(binding, annotation);
static createFromType(type: Type, annotation: DirectiveMetadata): DirectiveProvider {
var provider = new Provider(type, {toClass: type});
return DirectiveProvider.createFromProvider(provider, annotation);
}
}
@ -200,29 +201,29 @@ export class EventEmitterAccessor {
}
}
function _createEventEmitterAccessors(bwv: BindingWithVisibility): EventEmitterAccessor[] {
var binding = bwv.binding;
if (!(binding instanceof DirectiveBinding)) return [];
var db = <DirectiveBinding>binding;
function _createEventEmitterAccessors(bwv: ProviderWithVisibility): EventEmitterAccessor[] {
var provider = bwv.provider;
if (!(provider instanceof DirectiveProvider)) return [];
var db = <DirectiveProvider>provider;
return db.eventEmitters.map(eventConfig => {
var parsedEvent = EventConfig.parse(eventConfig);
return new EventEmitterAccessor(parsedEvent.eventName, reflector.getter(parsedEvent.fieldName));
});
}
function _createProtoQueryRefs(bindings: BindingWithVisibility[]): ProtoQueryRef[] {
function _createProtoQueryRefs(providers: ProviderWithVisibility[]): ProtoQueryRef[] {
var res = [];
ListWrapper.forEachWithIndex(bindings, (b, i) => {
if (b.binding instanceof DirectiveBinding) {
var directiveBinding = <DirectiveBinding>b.binding;
ListWrapper.forEachWithIndex(providers, (b, i) => {
if (b.provider instanceof DirectiveProvider) {
var directiveProvider = <DirectiveProvider>b.provider;
// field queries
var queries: QueryMetadataWithSetter[] = directiveBinding.queries;
var queries: QueryMetadataWithSetter[] = directiveProvider.queries;
queries.forEach(q => res.push(new ProtoQueryRef(i, q.setter, q.metadata)));
// queries passed into the constructor.
// TODO: remove this after constructor queries are no longer supported
var deps: DirectiveDependency[] =
<DirectiveDependency[]>directiveBinding.resolvedFactory.dependencies;
<DirectiveDependency[]>directiveProvider.resolvedFactory.dependencies;
deps.forEach(d => {
if (isPresent(d.queryDecorator)) res.push(new ProtoQueryRef(i, null, d.queryDecorator));
});
@ -238,67 +239,67 @@ export class ProtoElementInjector {
protoQueryRefs: ProtoQueryRef[];
protoInjector: ProtoInjector;
static create(parent: ProtoElementInjector, index: number, bindings: DirectiveBinding[],
firstBindingIsComponent: boolean, distanceToParent: number,
static create(parent: ProtoElementInjector, index: number, providers: DirectiveProvider[],
firstProviderIsComponent: boolean, distanceToParent: number,
directiveVariableBindings: Map<string, number>): ProtoElementInjector {
var bd = [];
ProtoElementInjector._createDirectiveBindingWithVisibility(bindings, bd,
firstBindingIsComponent);
if (firstBindingIsComponent) {
ProtoElementInjector._createViewBindingsWithVisibility(bindings, bd);
ProtoElementInjector._createDirectiveProviderWithVisibility(providers, bd,
firstProviderIsComponent);
if (firstProviderIsComponent) {
ProtoElementInjector._createViewProvidersWithVisibility(providers, bd);
}
ProtoElementInjector._createBindingsWithVisibility(bindings, bd);
return new ProtoElementInjector(parent, index, bd, distanceToParent, firstBindingIsComponent,
ProtoElementInjector._createProvidersWithVisibility(providers, bd);
return new ProtoElementInjector(parent, index, bd, distanceToParent, firstProviderIsComponent,
directiveVariableBindings);
}
private static _createDirectiveBindingWithVisibility(dirBindings: DirectiveBinding[],
bd: BindingWithVisibility[],
firstBindingIsComponent: boolean) {
dirBindings.forEach(dirBinding => {
bd.push(ProtoElementInjector._createBindingWithVisibility(firstBindingIsComponent, dirBinding,
dirBindings, dirBinding));
private static _createDirectiveProviderWithVisibility(dirProviders: DirectiveProvider[],
bd: ProviderWithVisibility[],
firstProviderIsComponent: boolean) {
dirProviders.forEach(dirProvider => {
bd.push(ProtoElementInjector._createProviderWithVisibility(
firstProviderIsComponent, dirProvider, dirProviders, dirProvider));
});
}
private static _createBindingsWithVisibility(dirBindings: DirectiveBinding[],
bd: BindingWithVisibility[]) {
var bindingsFromAllDirectives = [];
dirBindings.forEach(dirBinding => {
bindingsFromAllDirectives =
ListWrapper.concat(bindingsFromAllDirectives, dirBinding.bindings);
private static _createProvidersWithVisibility(dirProviders: DirectiveProvider[],
bd: ProviderWithVisibility[]) {
var providersFromAllDirectives = [];
dirProviders.forEach(dirProvider => {
providersFromAllDirectives =
ListWrapper.concat(providersFromAllDirectives, dirProvider.providers);
});
var resolved = Injector.resolve(bindingsFromAllDirectives);
resolved.forEach(b => bd.push(new BindingWithVisibility(b, Visibility.Public)));
var resolved = Injector.resolve(providersFromAllDirectives);
resolved.forEach(b => bd.push(new ProviderWithVisibility(b, Visibility.Public)));
}
private static _createBindingWithVisibility(firstBindingIsComponent: boolean,
dirBinding: DirectiveBinding,
dirBindings: DirectiveBinding[],
binding: ResolvedBinding) {
var isComponent = firstBindingIsComponent && dirBindings[0] === dirBinding;
return new BindingWithVisibility(binding,
isComponent ? Visibility.PublicAndPrivate : Visibility.Public);
private static _createProviderWithVisibility(firstProviderIsComponent: boolean,
dirProvider: DirectiveProvider,
dirProviders: DirectiveProvider[],
provider: ResolvedProvider) {
var isComponent = firstProviderIsComponent && dirProviders[0] === dirProvider;
return new ProviderWithVisibility(
provider, isComponent ? Visibility.PublicAndPrivate : Visibility.Public);
}
private static _createViewBindingsWithVisibility(dirBindings: DirectiveBinding[],
bd: BindingWithVisibility[]) {
var resolvedViewBindings = Injector.resolve(dirBindings[0].viewBindings);
resolvedViewBindings.forEach(b => bd.push(new BindingWithVisibility(b, Visibility.Private)));
private static _createViewProvidersWithVisibility(dirProviders: DirectiveProvider[],
bd: ProviderWithVisibility[]) {
var resolvedViewProviders = Injector.resolve(dirProviders[0].viewProviders);
resolvedViewProviders.forEach(b => bd.push(new ProviderWithVisibility(b, Visibility.Private)));
}
/** @internal */
public _firstBindingIsComponent: boolean;
public _firstProviderIsComponent: boolean;
constructor(public parent: ProtoElementInjector, public index: number,
bwv: BindingWithVisibility[], public distanceToParent: number,
_firstBindingIsComponent: boolean,
bwv: ProviderWithVisibility[], public distanceToParent: number,
_firstProviderIsComponent: boolean,
public directiveVariableBindings: Map<string, number>) {
this._firstBindingIsComponent = _firstBindingIsComponent;
this._firstProviderIsComponent = _firstProviderIsComponent;
var length = bwv.length;
this.protoInjector = new ProtoInjector(bwv);
this.eventEmitterAccessors = ListWrapper.createFixedSize(length);
@ -316,7 +317,7 @@ export class ProtoElementInjector {
get hasBindings(): boolean { return this.eventEmitterAccessors.length > 0; }
getBindingAtIndex(index: number): any { return this.protoInjector.getBindingAtIndex(index); }
getProviderAtIndex(index: number): any { return this.protoInjector.getProviderAtIndex(index); }
}
class _Context {
@ -456,12 +457,12 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
isComponentKey(key: Key): boolean { return this._strategy.isComponentKey(key); }
getDependency(injector: Injector, binding: ResolvedBinding, dep: Dependency): any {
getDependency(injector: Injector, provider: ResolvedProvider, dep: Dependency): any {
var key: Key = dep.key;
if (binding instanceof DirectiveBinding) {
if (provider instanceof DirectiveProvider) {
var dirDep = <DirectiveDependency>dep;
var dirBin = binding;
var dirProvider = provider;
var staticKeys = StaticKeys.instance();
@ -475,7 +476,7 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
if (dirDep.key.id === StaticKeys.instance().changeDetectorRefId) {
// We provide the component's view change detector to components and
// the surrounding component's change detector to directives.
if (dirBin.metadata instanceof ComponentMetadata) {
if (dirProvider.metadata instanceof ComponentMetadata) {
var componentView = this._preBuiltObjects.view.getNestedView(
this._preBuiltObjects.elementRef.boundElementIndex);
return componentView.changeDetector.ref;
@ -498,12 +499,12 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
return null;
}
throw new NoBindingError(null, dirDep.key);
throw new NoProviderError(null, dirDep.key);
}
return this._preBuiltObjects.templateRef;
}
} else if (binding instanceof PipeBinding) {
} else if (provider instanceof PipeProvider) {
if (dep.key.id === StaticKeys.instance().changeDetectorRefId) {
var componentView = this._preBuiltObjects.view.getNestedView(
this._preBuiltObjects.elementRef.boundElementIndex);
@ -753,7 +754,7 @@ interface _ElementInjectorStrategy {
}
/**
* Strategy used by the `ElementInjector` when the number of bindings is 10 or less.
* Strategy used by the `ElementInjector` when the number of providers is 10 or less.
* In such a case, inlining fields is beneficial for performances.
*/
class ElementInjectorInlineStrategy implements _ElementInjectorStrategy {
@ -764,26 +765,26 @@ class ElementInjectorInlineStrategy implements _ElementInjectorStrategy {
var p = i.protoStrategy;
i.resetConstructionCounter();
if (p.binding0 instanceof DirectiveBinding && isPresent(p.keyId0) && i.obj0 === UNDEFINED)
i.obj0 = i.instantiateBinding(p.binding0, p.visibility0);
if (p.binding1 instanceof DirectiveBinding && isPresent(p.keyId1) && i.obj1 === UNDEFINED)
i.obj1 = i.instantiateBinding(p.binding1, p.visibility1);
if (p.binding2 instanceof DirectiveBinding && isPresent(p.keyId2) && i.obj2 === UNDEFINED)
i.obj2 = i.instantiateBinding(p.binding2, p.visibility2);
if (p.binding3 instanceof DirectiveBinding && isPresent(p.keyId3) && i.obj3 === UNDEFINED)
i.obj3 = i.instantiateBinding(p.binding3, p.visibility3);
if (p.binding4 instanceof DirectiveBinding && isPresent(p.keyId4) && i.obj4 === UNDEFINED)
i.obj4 = i.instantiateBinding(p.binding4, p.visibility4);
if (p.binding5 instanceof DirectiveBinding && isPresent(p.keyId5) && i.obj5 === UNDEFINED)
i.obj5 = i.instantiateBinding(p.binding5, p.visibility5);
if (p.binding6 instanceof DirectiveBinding && isPresent(p.keyId6) && i.obj6 === UNDEFINED)
i.obj6 = i.instantiateBinding(p.binding6, p.visibility6);
if (p.binding7 instanceof DirectiveBinding && isPresent(p.keyId7) && i.obj7 === UNDEFINED)
i.obj7 = i.instantiateBinding(p.binding7, p.visibility7);
if (p.binding8 instanceof DirectiveBinding && isPresent(p.keyId8) && i.obj8 === UNDEFINED)
i.obj8 = i.instantiateBinding(p.binding8, p.visibility8);
if (p.binding9 instanceof DirectiveBinding && isPresent(p.keyId9) && i.obj9 === UNDEFINED)
i.obj9 = i.instantiateBinding(p.binding9, p.visibility9);
if (p.provider0 instanceof DirectiveProvider && isPresent(p.keyId0) && i.obj0 === UNDEFINED)
i.obj0 = i.instantiateProvider(p.provider0, p.visibility0);
if (p.provider1 instanceof DirectiveProvider && isPresent(p.keyId1) && i.obj1 === UNDEFINED)
i.obj1 = i.instantiateProvider(p.provider1, p.visibility1);
if (p.provider2 instanceof DirectiveProvider && isPresent(p.keyId2) && i.obj2 === UNDEFINED)
i.obj2 = i.instantiateProvider(p.provider2, p.visibility2);
if (p.provider3 instanceof DirectiveProvider && isPresent(p.keyId3) && i.obj3 === UNDEFINED)
i.obj3 = i.instantiateProvider(p.provider3, p.visibility3);
if (p.provider4 instanceof DirectiveProvider && isPresent(p.keyId4) && i.obj4 === UNDEFINED)
i.obj4 = i.instantiateProvider(p.provider4, p.visibility4);
if (p.provider5 instanceof DirectiveProvider && isPresent(p.keyId5) && i.obj5 === UNDEFINED)
i.obj5 = i.instantiateProvider(p.provider5, p.visibility5);
if (p.provider6 instanceof DirectiveProvider && isPresent(p.keyId6) && i.obj6 === UNDEFINED)
i.obj6 = i.instantiateProvider(p.provider6, p.visibility6);
if (p.provider7 instanceof DirectiveProvider && isPresent(p.keyId7) && i.obj7 === UNDEFINED)
i.obj7 = i.instantiateProvider(p.provider7, p.visibility7);
if (p.provider8 instanceof DirectiveProvider && isPresent(p.keyId8) && i.obj8 === UNDEFINED)
i.obj8 = i.instantiateProvider(p.provider8, p.visibility8);
if (p.provider9 instanceof DirectiveProvider && isPresent(p.keyId9) && i.obj9 === UNDEFINED)
i.obj9 = i.instantiateProvider(p.provider9, p.visibility9);
}
dehydrate() {
@ -805,34 +806,44 @@ class ElementInjectorInlineStrategy implements _ElementInjectorStrategy {
var i = this.injectorStrategy;
var p = i.protoStrategy;
if (p.binding0 instanceof DirectiveBinding && (<DirectiveBinding>p.binding0).callOnDestroy) {
if (p.provider0 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider0).callOnDestroy) {
i.obj0.onDestroy();
}
if (p.binding1 instanceof DirectiveBinding && (<DirectiveBinding>p.binding1).callOnDestroy) {
if (p.provider1 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider1).callOnDestroy) {
i.obj1.onDestroy();
}
if (p.binding2 instanceof DirectiveBinding && (<DirectiveBinding>p.binding2).callOnDestroy) {
if (p.provider2 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider2).callOnDestroy) {
i.obj2.onDestroy();
}
if (p.binding3 instanceof DirectiveBinding && (<DirectiveBinding>p.binding3).callOnDestroy) {
if (p.provider3 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider3).callOnDestroy) {
i.obj3.onDestroy();
}
if (p.binding4 instanceof DirectiveBinding && (<DirectiveBinding>p.binding4).callOnDestroy) {
if (p.provider4 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider4).callOnDestroy) {
i.obj4.onDestroy();
}
if (p.binding5 instanceof DirectiveBinding && (<DirectiveBinding>p.binding5).callOnDestroy) {
if (p.provider5 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider5).callOnDestroy) {
i.obj5.onDestroy();
}
if (p.binding6 instanceof DirectiveBinding && (<DirectiveBinding>p.binding6).callOnDestroy) {
if (p.provider6 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider6).callOnDestroy) {
i.obj6.onDestroy();
}
if (p.binding7 instanceof DirectiveBinding && (<DirectiveBinding>p.binding7).callOnDestroy) {
if (p.provider7 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider7).callOnDestroy) {
i.obj7.onDestroy();
}
if (p.binding8 instanceof DirectiveBinding && (<DirectiveBinding>p.binding8).callOnDestroy) {
if (p.provider8 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider8).callOnDestroy) {
i.obj8.onDestroy();
}
if (p.binding9 instanceof DirectiveBinding && (<DirectiveBinding>p.binding9).callOnDestroy) {
if (p.provider9 instanceof DirectiveProvider &&
(<DirectiveProvider>p.provider9).callOnDestroy) {
i.obj9.onDestroy();
}
}
@ -840,7 +851,7 @@ class ElementInjectorInlineStrategy implements _ElementInjectorStrategy {
getComponent(): any { return this.injectorStrategy.obj0; }
isComponentKey(key: Key): boolean {
return this._ei._proto._firstBindingIsComponent && isPresent(key) &&
return this._ei._proto._firstProviderIsComponent && isPresent(key) &&
key.id === this.injectorStrategy.protoStrategy.keyId0;
}
@ -848,51 +859,51 @@ class ElementInjectorInlineStrategy implements _ElementInjectorStrategy {
var i = this.injectorStrategy;
var p = i.protoStrategy;
if (isPresent(p.binding0) && p.binding0.key.token === query.selector) {
if (i.obj0 === UNDEFINED) i.obj0 = i.instantiateBinding(p.binding0, p.visibility0);
if (isPresent(p.provider0) && p.provider0.key.token === query.selector) {
if (i.obj0 === UNDEFINED) i.obj0 = i.instantiateProvider(p.provider0, p.visibility0);
list.push(i.obj0);
}
if (isPresent(p.binding1) && p.binding1.key.token === query.selector) {
if (i.obj1 === UNDEFINED) i.obj1 = i.instantiateBinding(p.binding1, p.visibility1);
if (isPresent(p.provider1) && p.provider1.key.token === query.selector) {
if (i.obj1 === UNDEFINED) i.obj1 = i.instantiateProvider(p.provider1, p.visibility1);
list.push(i.obj1);
}
if (isPresent(p.binding2) && p.binding2.key.token === query.selector) {
if (i.obj2 === UNDEFINED) i.obj2 = i.instantiateBinding(p.binding2, p.visibility2);
if (isPresent(p.provider2) && p.provider2.key.token === query.selector) {
if (i.obj2 === UNDEFINED) i.obj2 = i.instantiateProvider(p.provider2, p.visibility2);
list.push(i.obj2);
}
if (isPresent(p.binding3) && p.binding3.key.token === query.selector) {
if (i.obj3 === UNDEFINED) i.obj3 = i.instantiateBinding(p.binding3, p.visibility3);
if (isPresent(p.provider3) && p.provider3.key.token === query.selector) {
if (i.obj3 === UNDEFINED) i.obj3 = i.instantiateProvider(p.provider3, p.visibility3);
list.push(i.obj3);
}
if (isPresent(p.binding4) && p.binding4.key.token === query.selector) {
if (i.obj4 === UNDEFINED) i.obj4 = i.instantiateBinding(p.binding4, p.visibility4);
if (isPresent(p.provider4) && p.provider4.key.token === query.selector) {
if (i.obj4 === UNDEFINED) i.obj4 = i.instantiateProvider(p.provider4, p.visibility4);
list.push(i.obj4);
}
if (isPresent(p.binding5) && p.binding5.key.token === query.selector) {
if (i.obj5 === UNDEFINED) i.obj5 = i.instantiateBinding(p.binding5, p.visibility5);
if (isPresent(p.provider5) && p.provider5.key.token === query.selector) {
if (i.obj5 === UNDEFINED) i.obj5 = i.instantiateProvider(p.provider5, p.visibility5);
list.push(i.obj5);
}
if (isPresent(p.binding6) && p.binding6.key.token === query.selector) {
if (i.obj6 === UNDEFINED) i.obj6 = i.instantiateBinding(p.binding6, p.visibility6);
if (isPresent(p.provider6) && p.provider6.key.token === query.selector) {
if (i.obj6 === UNDEFINED) i.obj6 = i.instantiateProvider(p.provider6, p.visibility6);
list.push(i.obj6);
}
if (isPresent(p.binding7) && p.binding7.key.token === query.selector) {
if (i.obj7 === UNDEFINED) i.obj7 = i.instantiateBinding(p.binding7, p.visibility7);
if (isPresent(p.provider7) && p.provider7.key.token === query.selector) {
if (i.obj7 === UNDEFINED) i.obj7 = i.instantiateProvider(p.provider7, p.visibility7);
list.push(i.obj7);
}
if (isPresent(p.binding8) && p.binding8.key.token === query.selector) {
if (i.obj8 === UNDEFINED) i.obj8 = i.instantiateBinding(p.binding8, p.visibility8);
if (isPresent(p.provider8) && p.provider8.key.token === query.selector) {
if (i.obj8 === UNDEFINED) i.obj8 = i.instantiateProvider(p.provider8, p.visibility8);
list.push(i.obj8);
}
if (isPresent(p.binding9) && p.binding9.key.token === query.selector) {
if (i.obj9 === UNDEFINED) i.obj9 = i.instantiateBinding(p.binding9, p.visibility9);
if (isPresent(p.provider9) && p.provider9.key.token === query.selector) {
if (i.obj9 === UNDEFINED) i.obj9 = i.instantiateProvider(p.provider9, p.visibility9);
list.push(i.obj9);
}
}
}
/**
* Strategy used by the `ElementInjector` when the number of bindings is 10 or less.
* Strategy used by the `ElementInjector` when the number of providers is 10 or less.
* In such a case, inlining fields is beneficial for performances.
*/
class ElementInjectorDynamicStrategy implements _ElementInjectorStrategy {
@ -904,9 +915,9 @@ class ElementInjectorDynamicStrategy implements _ElementInjectorStrategy {
inj.resetConstructionCounter();
for (var i = 0; i < p.keyIds.length; i++) {
if (p.bindings[i] instanceof DirectiveBinding && isPresent(p.keyIds[i]) &&
if (p.providers[i] instanceof DirectiveProvider && isPresent(p.keyIds[i]) &&
inj.objs[i] === UNDEFINED) {
inj.objs[i] = inj.instantiateBinding(p.bindings[i], p.visibilities[i]);
inj.objs[i] = inj.instantiateProvider(p.providers[i], p.visibilities[i]);
}
}
}
@ -920,9 +931,9 @@ class ElementInjectorDynamicStrategy implements _ElementInjectorStrategy {
var ist = this.injectorStrategy;
var p = ist.protoStrategy;
for (var i = 0; i < p.bindings.length; i++) {
if (p.bindings[i] instanceof DirectiveBinding &&
(<DirectiveBinding>p.bindings[i]).callOnDestroy) {
for (var i = 0; i < p.providers.length; i++) {
if (p.providers[i] instanceof DirectiveProvider &&
(<DirectiveProvider>p.providers[i]).callOnDestroy) {
ist.objs[i].onDestroy();
}
}
@ -932,17 +943,17 @@ class ElementInjectorDynamicStrategy implements _ElementInjectorStrategy {
isComponentKey(key: Key): boolean {
var p = this.injectorStrategy.protoStrategy;
return this._ei._proto._firstBindingIsComponent && isPresent(key) && key.id === p.keyIds[0];
return this._ei._proto._firstProviderIsComponent && isPresent(key) && key.id === p.keyIds[0];
}
addDirectivesMatchingQuery(query: QueryMetadata, list: any[]): void {
var ist = this.injectorStrategy;
var p = ist.protoStrategy;
for (var i = 0; i < p.bindings.length; i++) {
if (p.bindings[i].key.token === query.selector) {
for (var i = 0; i < p.providers.length; i++) {
if (p.providers[i].key.token === query.selector) {
if (ist.objs[i] === UNDEFINED) {
ist.objs[i] = ist.instantiateBinding(p.bindings[i], p.visibilities[i]);
ist.objs[i] = ist.instantiateProvider(p.providers[i], p.visibilities[i]);
}
list.push(ist.objs[i]);
}
@ -1025,7 +1036,7 @@ export class QueryRef {
private _visitInjector(inj: ElementInjector, aggregator: any[]) {
if (this.protoQueryRef.query.isVarBindingQuery) {
this._aggregateVariableBindings(inj, aggregator);
this._aggregateVariableBinding(inj, aggregator);
} else {
this._aggregateDirective(inj, aggregator);
}
@ -1049,7 +1060,7 @@ export class QueryRef {
}
}
private _aggregateVariableBindings(inj: ElementInjector, aggregator: any[]): void {
private _aggregateVariableBinding(inj: ElementInjector, aggregator: any[]): void {
var vb = this.protoQueryRef.query.varBindings;
for (var i = 0; i < vb.length; ++i) {
if (inj.hasVariableBinding(vb[i])) {

View File

@ -3,14 +3,14 @@ import {isPresent, isBlank, Type, isArray, isNumber} from 'angular2/src/core/fac
import {RenderProtoViewRef} from 'angular2/src/core/render/api';
import {Injectable, Binding, resolveForwardRef, Inject} from 'angular2/src/core/di';
import {Injectable, Provider, resolveForwardRef, Inject} from 'angular2/src/core/di';
import {PipeBinding} from '../pipes/pipe_binding';
import {PipeProvider} from '../pipes/pipe_provider';
import {ProtoPipes} from '../pipes/pipes';
import {AppProtoView, AppProtoViewMergeInfo, ViewType} from './view';
import {ElementBinder} from './element_binder';
import {ProtoElementInjector, DirectiveBinding} from './element_injector';
import {ProtoElementInjector, DirectiveProvider} from './element_injector';
import {DirectiveResolver} from './directive_resolver';
import {ViewResolver} from './view_resolver';
import {PipeResolver} from './pipe_resolver';
@ -55,7 +55,7 @@ export class ProtoViewFactory {
var result = this._cache.get(compiledTemplate.id);
if (isBlank(result)) {
var templateData = compiledTemplate.getData(this._appId);
var emptyMap: {[key: string]: PipeBinding} = {};
var emptyMap: {[key: string]: PipeProvider} = {};
result = new AppProtoView(templateData.commands, ViewType.HOST, true,
templateData.changeDetectorFactory, null, new ProtoPipes(emptyMap));
this._cache.set(compiledTemplate.id, result);
@ -76,7 +76,7 @@ export class ProtoViewFactory {
nestedProtoView = new AppProtoView(compiledTemplateData.commands, ViewType.COMPONENT, true,
compiledTemplateData.changeDetectorFactory, null,
ProtoPipes.fromBindings(boundPipes));
ProtoPipes.fromProviders(boundPipes));
// Note: The cache is updated before recursing
// to be able to resolve cycles
this._cache.set(cmd.template.id, nestedProtoView);
@ -112,9 +112,9 @@ export class ProtoViewFactory {
initializer.variableLocations);
}
private _bindPipe(typeOrBinding): PipeBinding {
let meta = this._pipeResolver.resolve(typeOrBinding);
return PipeBinding.createFromType(typeOrBinding, meta);
private _bindPipe(typeOrProvider): PipeProvider {
let meta = this._pipeResolver.resolve(typeOrProvider);
return PipeProvider.createFromType(typeOrProvider, meta);
}
private _flattenPipes(view: ViewMetadata): any[] {
@ -245,12 +245,12 @@ function _createElementBinder(directiveResolver: DirectiveResolver, nestedProtoV
if (isBlank(parentProtoElementInjector)) {
distanceToParentPei = -1;
}
var componentDirectiveBinding: DirectiveBinding = null;
var componentDirectiveProvider: DirectiveProvider = null;
var isEmbeddedTemplate = false;
var directiveBindings: DirectiveBinding[] =
beginElementCmd.directives.map(type => bindDirective(directiveResolver, type));
var directiveProviders: DirectiveProvider[] =
beginElementCmd.directives.map(type => provideDirective(directiveResolver, type));
if (beginElementCmd instanceof BeginComponentCmd) {
componentDirectiveBinding = directiveBindings[0];
componentDirectiveProvider = directiveProviders[0];
} else if (beginElementCmd instanceof EmbeddedTemplateCmd) {
isEmbeddedTemplate = true;
}
@ -262,29 +262,29 @@ function _createElementBinder(directiveResolver: DirectiveResolver, nestedProtoV
// so that, when hydrating, $implicit can be set to the element.
// - <template> elements need their own ElementInjector so that we can query their TemplateRef
var hasVariables = beginElementCmd.variableNameAndValues.length > 0;
if (directiveBindings.length > 0 || hasVariables || isEmbeddedTemplate) {
if (directiveProviders.length > 0 || hasVariables || isEmbeddedTemplate) {
var directiveVariableBindings = new Map<string, number>();
if (!isEmbeddedTemplate) {
directiveVariableBindings =
createDirectiveVariableBindings(beginElementCmd.variableNameAndValues, directiveBindings);
directiveVariableBindings = createDirectiveVariableBindings(
beginElementCmd.variableNameAndValues, directiveProviders);
}
protoElementInjector = ProtoElementInjector.create(
parentProtoElementInjector, boundElementIndex, directiveBindings,
isPresent(componentDirectiveBinding), distanceToParentPei, directiveVariableBindings);
parentProtoElementInjector, boundElementIndex, directiveProviders,
isPresent(componentDirectiveProvider), distanceToParentPei, directiveVariableBindings);
protoElementInjector.attributes = arrayToMap(beginElementCmd.attrNameAndValues, false);
}
return new ElementBinder(boundElementIndex, parentElementBinder, distanceToParentBinder,
protoElementInjector, componentDirectiveBinding, nestedProtoView);
protoElementInjector, componentDirectiveProvider, nestedProtoView);
}
function bindDirective(directiveResolver: DirectiveResolver, type: Type): DirectiveBinding {
function provideDirective(directiveResolver: DirectiveResolver, type: Type): DirectiveProvider {
let annotation = directiveResolver.resolve(type);
return DirectiveBinding.createFromType(type, annotation);
return DirectiveProvider.createFromType(type, annotation);
}
export function createDirectiveVariableBindings(variableNameAndValues: Array<string | number>,
directiveBindings: DirectiveBinding[]):
directiveProviders: DirectiveProvider[]):
Map<string, number> {
var directiveVariableBindings = new Map<string, number>();
for (var i = 0; i < variableNameAndValues.length; i += 2) {
@ -313,7 +313,7 @@ function arrayToMap(arr: string[], inverse: boolean): Map<string, string> {
return result;
}
function _flattenList(tree: any[], out: Array<Type | Binding | any[]>): void {
function _flattenList(tree: any[], out: Array<Type | Provider | any[]>): void {
for (var i = 0; i < tree.length; i++) {
var item = resolveForwardRef(tree[i]);
if (isArray(item)) {

View File

@ -21,7 +21,7 @@ import {
ProtoElementInjector,
ElementInjector,
PreBuiltObjects,
DirectiveBinding
DirectiveProvider
} from './element_injector';
import {ElementBinder} from './element_binder';
import {isPresent, isBlank} from 'angular2/src/core/facade/lang';

View File

@ -1,6 +1,6 @@
import {ListWrapper} from 'angular2/src/core/facade/collection';
import {unimplemented} from 'angular2/src/core/facade/exceptions';
import {ResolvedBinding} from 'angular2/src/core/di';
import {ResolvedProvider} from 'angular2/src/core/di';
import {isPresent, isBlank} from 'angular2/src/core/facade/lang';
import * as avmModule from './view_manager';
@ -75,13 +75,13 @@ export abstract class ViewContainerRef {
*
* If `index` is not specified, the new View will be inserted as the last View in the container.
*
* You can optionally specify `dynamicallyCreatedBindings`, which configure the {@link Injector}
* You can optionally specify `dynamicallyCreatedProviders`, which configure the {@link Injector}
* that will be created for the Host View.
*
* Returns the {@link HostViewRef} of the Host View created for the newly instantiated Component.
*/
abstract createHostView(protoViewRef?: ProtoViewRef, index?: number,
dynamicallyCreatedBindings?: ResolvedBinding[]): HostViewRef;
dynamicallyCreatedProviders?: ResolvedProvider[]): HostViewRef;
/**
* Inserts a View identified by a {@link ViewRef} into the container at the specified `index`.
@ -136,10 +136,10 @@ export class ViewContainerRef_ extends ViewContainerRef {
}
createHostView(protoViewRef: ProtoViewRef = null, index: number = -1,
dynamicallyCreatedBindings: ResolvedBinding[] = null): HostViewRef {
dynamicallyCreatedProviders: ResolvedProvider[] = null): HostViewRef {
if (index == -1) index = this.length;
return this.viewManager.createHostViewInContainer(this.element, index, protoViewRef,
dynamicallyCreatedBindings);
dynamicallyCreatedProviders);
}
// TODO(i): refactor insert+remove into move

View File

@ -1,9 +1,9 @@
import {
Injector,
Inject,
Binding,
Provider,
Injectable,
ResolvedBinding,
ResolvedProvider,
forwardRef
} from 'angular2/src/core/di';
import {isPresent, isBlank} from 'angular2/src/core/facade/lang';
@ -159,7 +159,7 @@ export abstract class AppViewManager {
*/
abstract createHostViewInContainer(viewContainerLocation: ElementRef, index: number,
protoViewRef: ProtoViewRef,
imperativelyCreatedInjector: ResolvedBinding[]): HostViewRef;
imperativelyCreatedInjector: ResolvedProvider[]): HostViewRef;
/**
* Destroys an Embedded or Host View attached to a View Container at the specified `index`.
@ -278,7 +278,7 @@ export class AppViewManager_ extends AppViewManager {
createHostViewInContainer(viewContainerLocation: ElementRef, index: number,
protoViewRef: ProtoViewRef,
imperativelyCreatedInjector: ResolvedBinding[]): HostViewRef {
imperativelyCreatedInjector: ResolvedProvider[]): HostViewRef {
var s = this._createHostViewInContainerScope();
var protoView = internalProtoView(protoViewRef);
if (protoView.type !== viewModule.ViewType.HOST) {
@ -297,7 +297,7 @@ export class AppViewManager_ extends AppViewManager {
*/
_createViewInContainer(viewContainerLocation: ElementRef, index: number,
protoView: viewModule.AppProtoView, context: ElementRef,
imperativelyCreatedInjector: ResolvedBinding[]): ViewRef {
imperativelyCreatedInjector: ResolvedProvider[]): ViewRef {
var parentView = internalView((<ElementRef_>viewContainerLocation).parentView);
var boundElementIndex = (<ElementRef_>viewContainerLocation).boundElementIndex;
var contextView = internalView((<ElementRef_>context).parentView);

View File

@ -1,4 +1,4 @@
import {Injector, Binding, Injectable, ResolvedBinding} from 'angular2/src/core/di';
import {Injector, Provider, Injectable, ResolvedProvider} from 'angular2/src/core/di';
import {ListWrapper, MapWrapper, Map, StringMapWrapper} from 'angular2/src/core/facade/collection';
import * as eli from './element_injector';
import {isPresent, isBlank} from 'angular2/src/core/facade/lang';
@ -156,7 +156,7 @@ export class AppViewManagerUtils {
hydrateViewInContainer(parentView: viewModule.AppView, boundElementIndex: number,
contextView: viewModule.AppView, contextBoundElementIndex: number,
index: number, imperativelyCreatedBindings: ResolvedBinding[]) {
index: number, imperativelyCreatedProviders: ResolvedProvider[]) {
if (isBlank(contextView)) {
contextView = parentView;
contextBoundElementIndex = boundElementIndex;
@ -165,8 +165,8 @@ export class AppViewManagerUtils {
var view = viewContainer.views[index];
var elementInjector = contextView.elementInjectors[contextBoundElementIndex];
var injector = isPresent(imperativelyCreatedBindings) ?
Injector.fromResolvedBindings(imperativelyCreatedBindings) :
var injector = isPresent(imperativelyCreatedProviders) ?
Injector.fromResolvedProviders(imperativelyCreatedProviders) :
null;
this._hydrateView(view, injector, elementInjector.getHost(), contextView.context,
contextView.locals);

View File

@ -19,7 +19,8 @@ class Directive extends DirectiveMetadata {
@deprecated List<String> properties,
@deprecated List<String> events,
Map<String, String> host,
List bindings, String exportAs, String moduleId,
@deprecated List bindings,
List providers, String exportAs, String moduleId,
Map<String, dynamic> queries})
: super(
selector: selector,
@ -29,6 +30,7 @@ class Directive extends DirectiveMetadata {
events: events,
host: host,
bindings: bindings,
providers: providers,
exportAs: exportAs,
moduleId: moduleId,
queries: queries);
@ -43,9 +45,10 @@ class Component extends ComponentMetadata {
@deprecated List<String> properties,
@deprecated List<String> events,
Map<String, String> host,
List bindings, String exportAs, String moduleId,
@deprecated List bindings, List providers, String exportAs, String moduleId,
Map<String, dynamic> queries,
List viewBindings, ChangeDetectionStrategy changeDetection,
@deprecated List viewBindings,
List viewProviders, ChangeDetectionStrategy changeDetection,
String templateUrl, String template, dynamic directives,
dynamic pipes, ViewEncapsulation encapsulation, List<String> styles,
List<String> styleUrls
@ -58,9 +61,11 @@ class Component extends ComponentMetadata {
events: events,
host: host,
bindings: bindings,
providers: providers,
exportAs: exportAs,
moduleId: moduleId,
viewBindings: viewBindings,
viewProviders: viewProviders,
queries: queries,
changeDetection: changeDetection,
templateUrl: templateUrl,

View File

@ -153,6 +153,7 @@ export interface DirectiveFactory {
events?: string[],
host?: {[key: string]: string},
bindings?: any[],
providers?: any[],
exportAs?: string,
moduleId?: string,
queries?: {[key: string]: any}
@ -165,6 +166,7 @@ export interface DirectiveFactory {
events?: string[],
host?: {[key: string]: string},
bindings?: any[],
providers?: any[],
exportAs?: string,
moduleId?: string,
queries?: {[key: string]: any}
@ -222,11 +224,14 @@ export interface ComponentFactory {
properties?: string[],
events?: string[],
host?: {[key: string]: string},
/* @deprecated */
bindings?: any[],
providers?: any[],
exportAs?: string,
moduleId?: string,
queries?: {[key: string]: any},
viewBindings?: any[],
viewProviders?: any[],
changeDetection?: ChangeDetectionStrategy,
templateUrl?: string,
template?: string,
@ -243,11 +248,15 @@ export interface ComponentFactory {
properties?: string[],
events?: string[],
host?: {[key: string]: string},
/* @deprecated */
bindings?: any[],
providers?: any[],
exportAs?: string,
moduleId?: string,
queries?: {[key: string]: any},
/* @deprecated */
viewBindings?: any[],
viewProviders?: any[],
changeDetection?: ChangeDetectionStrategy,
templateUrl?: string,
template?: string,

View File

@ -466,13 +466,13 @@ export class DirectiveMetadata extends InjectableMetadata {
* ```
*
*/
inputs: string[];
/**
* @deprecated
* Same as `inputs`. This is to enable easier migration.
*/
properties: string[];
get inputs(): string[] {
return isPresent(this._properties) && this._properties.length > 0 ? this._properties :
this._inputs;
}
get properties(): string[] { return this.inputs; }
private _inputs: string[];
private _properties: string[];
/**
* Enumerates the set of event-bound output properties.
@ -519,13 +519,12 @@ export class DirectiveMetadata extends InjectableMetadata {
* ```
*
*/
outputs: string[];
/**
* @deprecated
* Same as `outputs`. This is to enable easier migration.
*/
events: string[];
get outputs(): string[] {
return isPresent(this._events) && this._events.length > 0 ? this._events : this._outputs;
}
get events(): string[] { return this.outputs; }
private _outputs: string[];
private _events: string[];
/**
* Specify the events, actions, properties and attributes related to the host element.
@ -665,7 +664,14 @@ export class DirectiveMetadata extends InjectableMetadata {
* }
* ```
*/
bindings: any[];
get providers(): any[] {
return isPresent(this._bindings) && this._bindings.length > 0 ? this._bindings :
this._providers;
}
/** @deprecated */
get bindings(): any[] { return this.providers; }
private _providers: any[];
private _bindings: any[];
/**
* Defines the name that can be used in the template to assign this directive to a variable.
@ -751,33 +757,32 @@ export class DirectiveMetadata extends InjectableMetadata {
*/
queries: {[key: string]: any};
constructor({selector, inputs, outputs, properties, events, host, bindings, exportAs, moduleId,
queries}: {
constructor({selector, inputs, outputs, properties, events, host, bindings, providers, exportAs,
moduleId, queries}: {
selector?: string,
inputs?: string[],
outputs?: string[],
properties?: string[],
events?: string[],
host?: {[key: string]: string},
bindings?: any[],
providers?: any[],
/** @deprecated */ bindings?: any[],
exportAs?: string,
moduleId?: string,
queries?: {[key: string]: any}
} = {}) {
super();
this.selector = selector;
this.inputs = inputs;
this.outputs = outputs;
this._inputs = inputs;
this._properties = properties;
this._outputs = outputs;
this._events = events;
this.host = host;
// TODO: remove this once properties and events are removed.
this.properties = properties;
this.events = events;
this.exportAs = exportAs;
this.moduleId = moduleId;
this.queries = queries;
this.bindings = bindings;
this._providers = providers;
this._bindings = bindings;
}
}
@ -792,7 +797,7 @@ export class DirectiveMetadata extends InjectableMetadata {
* When a component is instantiated, Angular
* - creates a shadow DOM for the component.
* - loads the selected template into the shadow DOM.
* - creates all the injectable objects configured with `bindings` and `viewBindings`.
* - creates all the injectable objects configured with `providers` and `viewProviders`.
*
* All template expressions and statements are then evaluated against the component instance.
*
@ -862,7 +867,7 @@ export class ComponentMetadata extends DirectiveMetadata {
*
* @Component({
* selector: 'greet',
* viewBindings: [
* viewProviders: [
* Greeter
* ]
* })
@ -875,7 +880,13 @@ export class ComponentMetadata extends DirectiveMetadata {
*
* ```
*/
viewBindings: any[];
get viewProviders(): any[] {
return isPresent(this._viewBindings) && this._viewBindings.length > 0 ? this._viewBindings :
this._viewProviders;
}
get viewBindings(): any[] { return this.viewProviders; }
private _viewProviders: any[];
private _viewBindings: any[];
templateUrl: string;
@ -892,18 +903,21 @@ export class ComponentMetadata extends DirectiveMetadata {
encapsulation: ViewEncapsulation;
constructor({selector, inputs, outputs, properties, events, host, exportAs, moduleId, bindings,
viewBindings, changeDetection = ChangeDetectionStrategy.Default, queries,
templateUrl, template, styleUrls, styles, directives, pipes, encapsulation}: {
providers, viewBindings, viewProviders,
changeDetection = ChangeDetectionStrategy.Default, queries, templateUrl, template,
styleUrls, styles, directives, pipes, encapsulation}: {
selector?: string,
inputs?: string[],
outputs?: string[],
properties?: string[],
events?: string[],
host?: {[key: string]: string},
bindings?: any[],
/** @deprecated */ bindings?: any[],
providers?: any[],
exportAs?: string,
moduleId?: string,
viewBindings?: any[],
/** @deprecated */ viewBindings?: any[],
viewProviders?: any[],
queries?: {[key: string]: any},
changeDetection?: ChangeDetectionStrategy,
templateUrl?: string,
@ -924,12 +938,13 @@ export class ComponentMetadata extends DirectiveMetadata {
exportAs: exportAs,
moduleId: moduleId,
bindings: bindings,
providers: providers,
queries: queries
});
this.changeDetection = changeDetection;
this.viewBindings = viewBindings;
this._viewProviders = viewProviders;
this._viewBindings = viewBindings;
this.templateUrl = templateUrl;
this.template = template;
this.styleUrls = styleUrls;

View File

@ -7,7 +7,7 @@ import {DatePipe} from './date_pipe';
import {DecimalPipe, PercentPipe, CurrencyPipe} from './number_pipe';
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
import {Binding, OpaqueToken} from 'angular2/src/core/di';
import {Provider, OpaqueToken} from 'angular2/src/core/di';
const DEFAULT_PIPES_LIST = CONST_EXPR([
AsyncPipe,
@ -23,5 +23,5 @@ const DEFAULT_PIPES_LIST = CONST_EXPR([
export const DEFAULT_PIPES_TOKEN: OpaqueToken = CONST_EXPR(new OpaqueToken("Default Pipes"));
export const DEFAULT_PIPES: Binding =
CONST_EXPR(new Binding(DEFAULT_PIPES_TOKEN, {toValue: DEFAULT_PIPES_LIST}));
export const DEFAULT_PIPES: Provider =
CONST_EXPR(new Provider(DEFAULT_PIPES_TOKEN, {toValue: DEFAULT_PIPES_LIST}));

View File

@ -1,18 +0,0 @@
import {Type} from 'angular2/src/core/facade/lang';
import {ResolvedFactory, resolveBinding, ResolvedBinding_} from 'angular2/src/core/di/binding';
import {Key, ResolvedBinding, Binding} from 'angular2/src/core/di';
import {PipeMetadata} from '../metadata/directives';
export class PipeBinding extends ResolvedBinding_ {
constructor(public name: string, public pure: boolean, key: Key,
resolvedFactories: ResolvedFactory[], multiBinding: boolean) {
super(key, resolvedFactories, multiBinding);
}
static createFromType(type: Type, metadata: PipeMetadata): PipeBinding {
var binding = new Binding(type, {toClass: type});
var rb = resolveBinding(binding);
return new PipeBinding(metadata.name, metadata.pure, rb.key, rb.resolvedFactories,
rb.multiBinding);
}
}

View File

@ -0,0 +1,18 @@
import {Type} from 'angular2/src/core/facade/lang';
import {ResolvedFactory, resolveProvider, ResolvedProvider_} from 'angular2/src/core/di/provider';
import {Key, ResolvedProvider, Provider} from 'angular2/src/core/di';
import {PipeMetadata} from '../metadata/directives';
export class PipeProvider extends ResolvedProvider_ {
constructor(public name: string, public pure: boolean, key: Key,
resolvedFactories: ResolvedFactory[], multiBinding: boolean) {
super(key, resolvedFactories, multiBinding);
}
static createFromType(type: Type, metadata: PipeMetadata): PipeProvider {
var provider = new Provider(type, {toClass: type});
var rb = resolveProvider(provider);
return new PipeProvider(metadata.name, metadata.pure, rb.key, rb.resolvedFactories,
rb.multiProvider);
}
}

View File

@ -5,17 +5,17 @@ import {
Injectable,
OptionalMetadata,
SkipSelfMetadata,
Binding,
Provider,
Injector,
bind
} from 'angular2/src/core/di';
import {PipeBinding} from './pipe_binding';
import {PipeProvider} from './pipe_provider';
import * as cd from 'angular2/src/core/change_detection/pipes';
export class ProtoPipes {
static fromBindings(bindings: PipeBinding[]): ProtoPipes {
var config: {[key: string]: PipeBinding} = {};
bindings.forEach(b => config[b.name] = b);
static fromProviders(providers: PipeProvider[]): ProtoPipes {
var config: {[key: string]: PipeProvider} = {};
providers.forEach(b => config[b.name] = b);
return new ProtoPipes(config);
}
@ -23,14 +23,14 @@ export class ProtoPipes {
/**
* Map of {@link PipeMetadata} names to {@link PipeMetadata} implementations.
*/
public config: {[key: string]: PipeBinding}) {
public config: {[key: string]: PipeProvider}) {
this.config = config;
}
get(name: string): PipeBinding {
var binding = this.config[name];
if (isBlank(binding)) throw new BaseException(`Cannot find pipe '${name}'.`);
return binding;
get(name: string): PipeProvider {
var provider = this.config[name];
if (isBlank(provider)) throw new BaseException(`Cannot find pipe '${name}'.`);
return provider;
}
}

View File

@ -7,4 +7,6 @@ import 'package:angular2/src/core/dom/dom_adapter.dart';
exceptionFactory() => new ExceptionHandler(DOM, true);
const EXCEPTION_BINDING = const Binding(ExceptionHandler, toFactory: exceptionFactory, deps: const []);
const EXCEPTION_PROVIDER = const Binding(ExceptionHandler, toFactory: exceptionFactory, deps: const []);
const EXCEPTION_BINDING = EXCEPTION_PROVIDER;

View File

@ -1,6 +1,8 @@
import {bind} from 'angular2/src/core/di';
import {provide} from 'angular2/src/core/di';
import {ExceptionHandler} from 'angular2/src/core/facade/exceptions';
import {DOM} from 'angular2/src/core/dom/dom_adapter';
export const EXCEPTION_BINDING =
bind(ExceptionHandler).toFactory(() => new ExceptionHandler(DOM, false), []);
export const EXCEPTION_PROVIDER =
provide(ExceptionHandler, {asFactory: () => new ExceptionHandler(DOM, false), deps: []});
export const EXCEPTION_BINDING = EXCEPTION_PROVIDER;

View File

@ -15,8 +15,12 @@ class PublicTestability {
whenStable(callback: Function) { this._testability.whenStable(callback); }
findBindings(using: any, binding: string, exactMatch: boolean): any[] {
return this._testability.findBindings(using, binding, exactMatch);
findBindings(using: any, provider: string, exactMatch: boolean): any[] {
return this.findProviders(using, provider, exactMatch);
}
findProviders(using: any, provider: string, exactMatch: boolean): any[] {
return this._testability.findBindings(using, provider, exactMatch);
}
}

View File

@ -72,7 +72,12 @@ export class Testability {
// check for stability.
isAngularEventPending(): boolean { return this._isAngularEventPending; }
findBindings(using: any, binding: string, exactMatch: boolean): any[] {
findBindings(using: any, provider: string, exactMatch: boolean): any[] {
// TODO(juliemr): implement.
return [];
}
findProviders(using: any, provider: string, exactMatch: boolean): any[] {
// TODO(juliemr): implement.
return [];
}