@ -6,16 +6,27 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {unimplemented} from '../facade/exceptions';
|
||||
import {BaseException, unimplemented} from '../facade/exceptions';
|
||||
import {stringify} from '../facade/lang';
|
||||
|
||||
const _THROW_IF_NOT_FOUND = /*@ts2dart_const*/ new Object();
|
||||
export const THROW_IF_NOT_FOUND = /*@ts2dart_const*/ _THROW_IF_NOT_FOUND;
|
||||
|
||||
class _NullInjector implements Injector {
|
||||
get(token: any, notFoundValue: any = _THROW_IF_NOT_FOUND): any {
|
||||
if (notFoundValue === _THROW_IF_NOT_FOUND) {
|
||||
throw new BaseException(`No provider for ${stringify(token)}!`);
|
||||
}
|
||||
return notFoundValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @stable
|
||||
*/
|
||||
export abstract class Injector {
|
||||
static THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
|
||||
static NULL: Injector = new _NullInjector();
|
||||
|
||||
/**
|
||||
* Retrieves an instance from the injector based on the provided token.
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
// Public API for compiler
|
||||
export {AppModuleFactory, AppModuleRef} from './linker/app_module_factory';
|
||||
export {Compiler} from './linker/compiler';
|
||||
export {ComponentFactory, ComponentRef} from './linker/component_factory';
|
||||
export {ComponentFactoryResolver, NoComponentFactoryError} from './linker/component_factory_resolver';
|
||||
|
90
modules/@angular/core/src/linker/app_module_factory.ts
Normal file
90
modules/@angular/core/src/linker/app_module_factory.ts
Normal file
@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injector, THROW_IF_NOT_FOUND} from '../di/injector';
|
||||
import {unimplemented} from '../facade/exceptions';
|
||||
import {ConcreteType} from '../facade/lang';
|
||||
|
||||
import {ComponentFactory} from './component_factory';
|
||||
import {CodegenComponentFactoryResolver, ComponentFactoryResolver} from './component_factory_resolver';
|
||||
|
||||
|
||||
/**
|
||||
* Represents an instance of an AppModule created via a {@link AppModuleFactory}.
|
||||
*
|
||||
* `AppModuleRef` provides access to the AppModule Instance as well other objects related to this
|
||||
* AppModule Instance.
|
||||
* @stable
|
||||
*/
|
||||
export abstract class AppModuleRef<T> {
|
||||
/**
|
||||
* The injector that contains all of the providers of the AppModule.
|
||||
*/
|
||||
get injector(): Injector { return unimplemented(); }
|
||||
|
||||
/**
|
||||
* The ComponentFactoryResolver to get hold of the ComponentFactories
|
||||
* delcared in the `precompile` property of the module.
|
||||
*/
|
||||
get componentFactoryResolver(): ComponentFactoryResolver { return unimplemented(); }
|
||||
|
||||
/**
|
||||
* The AppModule instance.
|
||||
*/
|
||||
get instance(): T { return unimplemented(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @stable
|
||||
*/
|
||||
export class AppModuleFactory<T> {
|
||||
constructor(
|
||||
private _injectorClass: {new (parentInjector: Injector): AppModuleInjector<T>},
|
||||
private _moduleype: ConcreteType<T>) {}
|
||||
|
||||
get moduleType(): ConcreteType<T> { return this._moduleype; }
|
||||
|
||||
create(parentInjector: Injector = null): AppModuleRef<T> {
|
||||
if (!parentInjector) {
|
||||
parentInjector = Injector.NULL;
|
||||
}
|
||||
var instance = new this._injectorClass(parentInjector);
|
||||
instance.create();
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
const _UNDEFINED = new Object();
|
||||
|
||||
export abstract class AppModuleInjector<T> extends CodegenComponentFactoryResolver implements
|
||||
Injector,
|
||||
AppModuleRef<T> {
|
||||
public instance: T;
|
||||
|
||||
constructor(public parent: Injector, factories: ComponentFactory<any>[]) {
|
||||
super(factories, parent.get(ComponentFactoryResolver, ComponentFactoryResolver.NULL));
|
||||
}
|
||||
|
||||
create() { this.instance = this.createInternal(); }
|
||||
|
||||
abstract createInternal(): T;
|
||||
|
||||
get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {
|
||||
if (token === Injector || token === ComponentFactoryResolver) {
|
||||
return this;
|
||||
}
|
||||
var result = this.getInternal(token, _UNDEFINED);
|
||||
return result === _UNDEFINED ? this.parent.get(token, notFoundValue) : result;
|
||||
}
|
||||
|
||||
abstract getInternal(token: any, notFoundValue: any): any;
|
||||
|
||||
get injector(): Injector { return this; }
|
||||
|
||||
get componentFactoryResolver(): ComponentFactoryResolver { return this; }
|
||||
}
|
@ -8,7 +8,9 @@
|
||||
|
||||
import {BaseException} from '../facade/exceptions';
|
||||
import {ConcreteType, Type, stringify} from '../facade/lang';
|
||||
import {AppModuleMetadata} from '../metadata/app_module';
|
||||
|
||||
import {AppModuleFactory} from './app_module_factory';
|
||||
import {ComponentFactory} from './component_factory';
|
||||
|
||||
|
||||
@ -22,7 +24,10 @@ export class Compiler {
|
||||
/**
|
||||
* Loads the template and styles of a component and returns the associated `ComponentFactory`.
|
||||
*/
|
||||
compileComponentAsync<T>(component: ConcreteType<T>): Promise<ComponentFactory<T>> {
|
||||
compileComponentAsync<T>(component: ConcreteType<T>, {moduleDirectives = [], modulePipes = []}: {
|
||||
moduleDirectives?: ConcreteType<any>[],
|
||||
modulePipes?: ConcreteType<any>[]
|
||||
} = {}): Promise<ComponentFactory<T>> {
|
||||
throw new BaseException(
|
||||
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
|
||||
}
|
||||
@ -30,16 +35,37 @@ export class Compiler {
|
||||
* Compiles the given component. All templates have to be either inline or compiled via
|
||||
* `compileComponentAsync` before.
|
||||
*/
|
||||
compileComponentSync<T>(component: ConcreteType<T>): ComponentFactory<T> {
|
||||
compileComponentSync<T>(component: ConcreteType<T>, {moduleDirectives = [], modulePipes = []}: {
|
||||
moduleDirectives?: ConcreteType<any>[],
|
||||
modulePipes?: ConcreteType<any>[]
|
||||
} = {}): ComponentFactory<T> {
|
||||
throw new BaseException(
|
||||
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
|
||||
}
|
||||
/**
|
||||
* Compiles the given App Module. All templates of the components listed in `precompile`
|
||||
* have to be either inline or compiled before via `compileComponentAsync` /
|
||||
* `compileAppModuleAsync`.
|
||||
*/
|
||||
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
AppModuleFactory<T> {
|
||||
throw new BaseException(
|
||||
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
||||
}
|
||||
|
||||
compileAppModuleAsync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
Promise<AppModuleFactory<T>> {
|
||||
throw new BaseException(
|
||||
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all caches
|
||||
*/
|
||||
clearCache(): void {}
|
||||
|
||||
/**
|
||||
* Clears the cache for the given component.
|
||||
* Clears the cache for the given component/appModule.
|
||||
*/
|
||||
clearCacheFor(compType: Type) {}
|
||||
clearCacheFor(type: Type) {}
|
||||
}
|
||||
|
@ -14,10 +14,12 @@
|
||||
import {ChangeDetectionStrategy} from '../src/change_detection/change_detection';
|
||||
|
||||
import {AnimationEntryMetadata} from './animation/metadata';
|
||||
import {AppModuleMetadata} from './metadata/app_module';
|
||||
import {AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di';
|
||||
import {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
||||
import {ViewEncapsulation, ViewMetadata} from './metadata/view';
|
||||
|
||||
export {AppModuleMetadata} from './metadata/app_module';
|
||||
export {AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di';
|
||||
export {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
||||
export {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnDestroy, OnInit} from './metadata/lifecycle_hooks';
|
||||
@ -83,6 +85,16 @@ export interface ViewDecorator extends TypeDecorator {
|
||||
}): ViewDecorator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the {@link AppModuleMetadata} decorator function.
|
||||
*
|
||||
* See {@link AppModuleMetadataFactory}.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export interface AppModuleDecorator extends TypeDecorator {}
|
||||
|
||||
|
||||
/**
|
||||
* {@link DirectiveMetadata} factory for creating annotations, decorators or DSL.
|
||||
*
|
||||
@ -477,6 +489,28 @@ export interface HostListenerMetadataFactory {
|
||||
new (eventName: string, args?: string[]): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link AppModuleMetadata} factory for creating annotations, decorators or DSL.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export interface AppModuleMetadataFactory {
|
||||
(obj: {
|
||||
providers?: any[],
|
||||
directives?: Array<Type|any[]>,
|
||||
pipes?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>,
|
||||
modules?: Array<Type|any[]>,
|
||||
}): AppModuleDecorator;
|
||||
new (obj: {
|
||||
providers?: any[],
|
||||
directives?: Array<Type|any[]>,
|
||||
pipes?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>,
|
||||
modules?: Array<Type|any[]>,
|
||||
}): AppModuleMetadata;
|
||||
}
|
||||
|
||||
// TODO(alexeagle): remove the duplication of this doc. It is copied from ComponentMetadata.
|
||||
/**
|
||||
* Declare reusable UI building blocks for an application.
|
||||
@ -1499,3 +1533,11 @@ export var HostBinding: HostBindingMetadataFactory = makePropDecorator(HostBindi
|
||||
* @Annotation
|
||||
*/
|
||||
export var HostListener: HostListenerMetadataFactory = makePropDecorator(HostListenerMetadata);
|
||||
|
||||
/**
|
||||
* Declares an app module.
|
||||
* @stable
|
||||
* @Annotation
|
||||
*/
|
||||
export var AppModule: AppModuleMetadataFactory =
|
||||
<AppModuleMetadataFactory>makeDecorator(AppModuleMetadata);
|
||||
|
113
modules/@angular/core/src/metadata/app_module.ts
Normal file
113
modules/@angular/core/src/metadata/app_module.ts
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {InjectableMetadata} from '../di/metadata';
|
||||
import {Type} from '../facade/lang';
|
||||
|
||||
/**
|
||||
* Declares an Application Module.
|
||||
* @stable
|
||||
*/
|
||||
export class AppModuleMetadata extends InjectableMetadata {
|
||||
/**
|
||||
* Defines the set of injectable objects that are available in the injector
|
||||
* of this module.
|
||||
*
|
||||
* ## Simple Example
|
||||
*
|
||||
* Here is an example of a class that can be injected:
|
||||
*
|
||||
* ```
|
||||
* class Greeter {
|
||||
* greet(name:string) {
|
||||
* return 'Hello ' + name + '!';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @AppModule({
|
||||
* providers: [
|
||||
* Greeter
|
||||
* ]
|
||||
* })
|
||||
* class HelloWorld {
|
||||
* greeter:Greeter;
|
||||
*
|
||||
* constructor(greeter:Greeter) {
|
||||
* this.greeter = greeter;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
get providers(): any[] { return this._providers; }
|
||||
private _providers: any[];
|
||||
|
||||
|
||||
/**
|
||||
* Specifies a list of directives that can be used within the template
|
||||
* of any component that is part of this application module.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```javascript
|
||||
* @AppModule({
|
||||
* directives: [NgFor]
|
||||
* })
|
||||
* class MyAppModule {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
directives: Array<Type|any[]>;
|
||||
|
||||
/**
|
||||
* Specifies a list of pipes that can be used within the template
|
||||
* of any component that is part of this application module.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```javascript
|
||||
* @AppModule({
|
||||
* pipes: [SomePipe]
|
||||
* })
|
||||
* class MyAppModule {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
pipes: Array<Type|any[]>;
|
||||
|
||||
/**
|
||||
* Defines the components that should be precompiled as well when
|
||||
* this component is defined. For each components listed here,
|
||||
* Angular will create a {@link ComponentFactory ComponentFactory} and store it in the
|
||||
* {@link ComponentFactoryResolver ComponentFactoryResolver}.
|
||||
*/
|
||||
precompile: Array<Type|any[]>;
|
||||
|
||||
/**
|
||||
* Defines modules that should be included into this module.
|
||||
* The providers / directives / pipes / precompile entries will be added
|
||||
* to this module.
|
||||
* Just like the main module, the modules listed here are also eagerly
|
||||
* created and accessible via DI.
|
||||
*/
|
||||
modules: Array<Type|any[]>;
|
||||
|
||||
constructor({providers, directives, pipes, precompile, modules}: {
|
||||
providers?: any[],
|
||||
directives?: Array<Type|any[]>,
|
||||
pipes?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>,
|
||||
modules?: Array<Type|any[]>
|
||||
} = {}) {
|
||||
super();
|
||||
this._providers = providers;
|
||||
this.directives = directives;
|
||||
this.pipes = pipes;
|
||||
this.precompile = precompile;
|
||||
this.modules = modules;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user