refactor(core): change module semantics

This contains major changes to the compiler, bootstrap of the platforms
and test environment initialization.

Main part of #10043
Closes #10164

BREAKING CHANGE:
- Semantics and name of `@AppModule` (now `@NgModule`) changed quite a bit.
  This is actually not breaking as `@AppModules` were not part of rc.4.
  We will have detailed docs on `@NgModule` separately.
- `coreLoadAndBootstrap` and `coreBootstrap` can't be used any more (without migration support).
  Use `bootstrapModule` / `bootstrapModuleFactory` instead.
- All Components listed in routes have to be part of the `declarations` of an NgModule.
  Either directly on the bootstrap module / lazy loaded module, or in an NgModule imported by them.
This commit is contained in:
Tobias Bosch
2016-07-18 03:50:31 -07:00
parent ca16fc29a6
commit 46b212706b
129 changed files with 3580 additions and 3366 deletions
@@ -1,56 +0,0 @@
/**
* @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 {Type} from '../src/facade/lang';
import {APPLICATION_CORE_PROVIDERS} from './application_ref';
import {APP_ID_RANDOM_PROVIDER} from './application_tokens';
import {IterableDiffers, KeyValueDiffers, defaultIterableDiffers, defaultKeyValueDiffers} from './change_detection/change_detection';
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
import {ComponentResolver, ReflectorComponentResolver} from './linker/component_resolver';
import {DynamicComponentLoader, DynamicComponentLoader_} from './linker/dynamic_component_loader';
import {ViewUtils} from './linker/view_utils';
let __unused: Type; // avoid unused import when Type union types are erased
export function _componentFactoryResolverFactory() {
return ComponentFactoryResolver.NULL;
}
export function _iterableDiffersFactory() {
return defaultIterableDiffers;
}
export function _keyValueDiffersFactory() {
return defaultKeyValueDiffers;
}
/**
* A default set of providers which should be included in any Angular
* application, regardless of the platform it runs onto.
* @stable
*/
export const APPLICATION_COMMON_PROVIDERS: Array<Type|{[k: string]: any}|any[]> =
/*@ts2dart_const*/[
APPLICATION_CORE_PROVIDERS,
/* @ts2dart_Provider */ {provide: ComponentResolver, useClass: ReflectorComponentResolver},
{provide: ComponentFactoryResolver, useFactory: _componentFactoryResolverFactory, deps: []},
APP_ID_RANDOM_PROVIDER,
ViewUtils,
/* @ts2dart_Provider */ {
provide: IterableDiffers,
useFactory: _iterableDiffersFactory,
deps: []
},
/* @ts2dart_Provider */ {
provide: KeyValueDiffers,
useFactory: _keyValueDiffersFactory,
deps: []
},
/* @ts2dart_Provider */ {provide: DynamicComponentLoader, useClass: DynamicComponentLoader_},
];
@@ -0,0 +1,84 @@
/**
* @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 {Type} from '../src/facade/lang';
import {ApplicationRef, ApplicationRef_, isDevMode} from './application_ref';
import {APP_ID_RANDOM_PROVIDER} from './application_tokens';
import {IterableDiffers, KeyValueDiffers, defaultIterableDiffers, defaultKeyValueDiffers} from './change_detection/change_detection';
import {OptionalMetadata, SkipSelfMetadata} from './di';
import {Compiler} from './linker/compiler';
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
import {ComponentResolver} from './linker/component_resolver';
import {DynamicComponentLoader, DynamicComponentLoader_} from './linker/dynamic_component_loader';
import {ViewUtils} from './linker/view_utils';
import {NgModule} from './metadata';
import {NgZone} from './zone/ng_zone';
let __unused: Type; // avoid unused import when Type union types are erased
export function _componentFactoryResolverFactory() {
return ComponentFactoryResolver.NULL;
}
export function _iterableDiffersFactory() {
return defaultIterableDiffers;
}
export function _keyValueDiffersFactory() {
return defaultKeyValueDiffers;
}
export function createNgZone(parent: NgZone): NgZone {
// If an NgZone is already present in the parent injector,
// use that one. Creating the NgZone in the same injector as the
// application is dangerous as some services might get created before
// the NgZone has been created.
// We keep the NgZone factory in the application providers for
// backwards compatibility for now though.
if (parent) {
return parent;
}
return new NgZone({enableLongStackTrace: isDevMode()});
}
/**
* A default set of providers which should be included in any Angular
* application, regardless of the platform it runs onto.
*
* @deprecated Include `ApplicationModule` instead.
*/
export const APPLICATION_COMMON_PROVIDERS: Array<Type|{[k: string]: any}|any[]> = [];
/**
* This module includes the providers of @angular/core that are needed
* to bootstrap components via `ApplicationRef`.
*
* @experimental
*/
@NgModule({
providers: [
{
provide: NgZone,
useFactory: createNgZone,
deps: <any>[[new SkipSelfMetadata(), new OptionalMetadata(), NgZone]]
},
ApplicationRef_,
{provide: ApplicationRef, useExisting: ApplicationRef_},
Compiler,
{provide: ComponentResolver, useExisting: Compiler},
{provide: ComponentFactoryResolver, useFactory: _componentFactoryResolverFactory},
APP_ID_RANDOM_PROVIDER,
ViewUtils,
{provide: IterableDiffers, useFactory: _iterableDiffersFactory},
{provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory},
{provide: DynamicComponentLoader, useClass: DynamicComponentLoader_},
]
})
export class ApplicationModule {
}
+33 -66
View File
@@ -14,35 +14,16 @@ import {ConcreteType, IS_DART, Type, isBlank, isPresent, isPromise} from '../src
import {APP_INITIALIZER, PLATFORM_INITIALIZER} from './application_tokens';
import {ChangeDetectorRef} from './change_detection/change_detector_ref';
import {Console} from './console';
import {Inject, Injectable, Injector, OpaqueToken, Optional, OptionalMetadata, ReflectiveInjector, SkipSelf, SkipSelfMetadata, forwardRef} from './di';
import {AppModuleFactory, AppModuleRef} from './linker/app_module_factory';
import {Inject, Injectable, Injector, OpaqueToken, Optional, ReflectiveInjector, SkipSelf, forwardRef} from './di';
import {Compiler, CompilerFactory, CompilerOptions} from './linker/compiler';
import {ComponentFactory, ComponentRef} from './linker/component_factory';
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
import {ComponentResolver} from './linker/component_resolver';
import {NgModuleFactory, NgModuleRef} from './linker/ng_module_factory';
import {WtfScopeFn, wtfCreateScope, wtfLeave} from './profile/profile';
import {Testability, TestabilityRegistry} from './testability/testability';
import {NgZone, NgZoneError} from './zone/ng_zone';
/**
* Create an Angular zone.
* @experimental
*/
export function createNgZone(parent: NgZone): NgZone {
// If an NgZone is already present in the parent injector,
// use that one. Creating the NgZone in the same injector as the
// application is dangerous as some services might get created before
// the NgZone has been created.
// We keep the NgZone factory in the application providers for
// backwards compatibility for now though.
if (parent) {
return parent;
}
return new NgZone({enableLongStackTrace: isDevMode()});
}
var _devMode: boolean = true;
var _runModeLocked: boolean = false;
var _platform: PlatformRef;
@@ -113,17 +94,30 @@ export function createPlatform(injector: Injector): PlatformRef {
return _platform;
}
/**
* Factory for a platform.
*
* @experimental
*/
export type PlatformFactory = (extraProviders?: any[]) => PlatformRef;
/**
* Creates a fatory for a platform
*
* @experimental APIs related to application bootstrap are currently under review.
*/
export function createPlatformFactory(name: string, providers: any[]): () => PlatformRef {
export function createPlatformFactory(
parentPlaformFactory: PlatformFactory, name: string, providers: any[] = []): PlatformFactory {
const marker = new OpaqueToken(`Platform: ${name}`);
return () => {
return (extraProviders: any[] = []) => {
if (!getPlatform()) {
createPlatform(
ReflectiveInjector.resolveAndCreate(providers.concat({provide: marker, useValue: true})));
if (parentPlaformFactory) {
parentPlaformFactory(
providers.concat(extraProviders).concat({provide: marker, useValue: true}));
} else {
createPlatform(ReflectiveInjector.resolveAndCreate(
providers.concat(extraProviders).concat({provide: marker, useValue: true})));
}
}
return assertPlatform(marker);
};
@@ -168,7 +162,7 @@ export function getPlatform(): PlatformRef {
}
/**
* Creates an instance of an `@AppModule` for the given platform
* Creates an instance of an `@NgModule` for the given platform
* for offline compilation.
*
* ## Simple Example
@@ -176,8 +170,8 @@ export function getPlatform(): PlatformRef {
* ```typescript
* my_module.ts:
*
* @AppModule({
* modules: [BrowserModule]
* @NgModule({
* imports: [BrowserModule]
* })
* class MyModule {}
*
@@ -192,11 +186,11 @@ export function getPlatform(): PlatformRef {
* @experimental APIs related to application bootstrap are currently under review.
*/
export function bootstrapModuleFactory<M>(
moduleFactory: AppModuleFactory<M>, platform: PlatformRef): AppModuleRef<M> {
moduleFactory: NgModuleFactory<M>, platform: PlatformRef): NgModuleRef<M> {
// Note: We need to create the NgZone _before_ we instantiate the module,
// as instantiating the module creates some providers eagerly.
// So we create a mini parent injector that just contains the new NgZone and
// pass that as parent to the AppModuleFactory.
// pass that as parent to the NgModuleFactory.
const ngZone = new NgZone({enableLongStackTrace: isDevMode()});
const ngZoneInjector =
ReflectiveInjector.resolveAndCreate([{provide: NgZone, useValue: ngZone}], platform.injector);
@@ -204,13 +198,13 @@ export function bootstrapModuleFactory<M>(
}
/**
* Creates an instance of an `@AppModule` for a given platform using the given runtime compiler.
* Creates an instance of an `@NgModule` for a given platform using the given runtime compiler.
*
* ## Simple Example
*
* ```typescript
* @AppModule({
* modules: [BrowserModule]
* @NgModule({
* imports: [BrowserModule]
* })
* class MyModule {}
*
@@ -220,10 +214,11 @@ export function bootstrapModuleFactory<M>(
*/
export function bootstrapModule<M>(
moduleType: ConcreteType<M>, platform: PlatformRef,
compilerOptions: CompilerOptions = {}): Promise<AppModuleRef<M>> {
compilerOptions: CompilerOptions | CompilerOptions[] = []): Promise<NgModuleRef<M>> {
const compilerFactory: CompilerFactory = platform.injector.get(CompilerFactory);
const compiler = compilerFactory.createCompiler(compilerOptions);
return compiler.compileAppModuleAsync(moduleType)
const compiler = compilerFactory.createCompiler(
compilerOptions instanceof Array ? compilerOptions : [compilerOptions]);
return compiler.compileModuleAsync(moduleType)
.then((moduleFactory) => bootstrapModuleFactory(moduleFactory, platform))
.then((moduleRef) => {
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
@@ -239,10 +234,7 @@ export function bootstrapModule<M>(
*/
export function coreBootstrap<C>(
componentFactory: ComponentFactory<C>, injector: Injector): ComponentRef<C> {
let console = injector.get(Console);
console.warn('coreBootstrap is deprecated. Use bootstrapModuleFactory instead.');
var appRef: ApplicationRef = injector.get(ApplicationRef);
return appRef.bootstrap(componentFactory);
throw new BaseException('coreBootstrap is deprecated. Use bootstrapModuleFactory instead.');
}
/**
@@ -254,15 +246,7 @@ export function coreBootstrap<C>(
*/
export function coreLoadAndBootstrap(
componentType: Type, injector: Injector): Promise<ComponentRef<any>> {
let console = injector.get(Console);
console.warn('coreLoadAndBootstrap is deprecated. Use bootstrapModule instead.');
var appRef: ApplicationRef = injector.get(ApplicationRef);
return appRef.run(() => {
var componentResolver: ComponentResolver = injector.get(ComponentResolver);
return PromiseWrapper
.all([componentResolver.resolveComponent(componentType), appRef.waitForAsyncInitializers()])
.then((arr) => appRef.bootstrap(arr[0]));
});
throw new BaseException('coreLoadAndBootstrap is deprecated. Use bootstrapModule instead.');
}
/**
@@ -592,20 +576,3 @@ export class ApplicationRef_ extends ApplicationRef {
get componentTypes(): Type[] { return this._rootComponentTypes; }
}
export const PLATFORM_CORE_PROVIDERS =
/*@ts2dart_const*/[
PlatformRef_,
/*@ts2dart_const*/ (
/* @ts2dart_Provider */ {provide: PlatformRef, useExisting: PlatformRef_})
];
export const APPLICATION_CORE_PROVIDERS = /*@ts2dart_const*/[
/* @ts2dart_Provider */ {
provide: NgZone,
useFactory: createNgZone,
deps: <any>[[new SkipSelfMetadata(), new OptionalMetadata(), NgZone]]
},
ApplicationRef_,
/* @ts2dart_Provider */ {provide: ApplicationRef, useExisting: ApplicationRef_},
];
+3 -3
View File
@@ -7,8 +7,6 @@
*/
// Public API for compiler
export {AppModuleFactory, AppModuleRef} from './linker/app_module_factory';
export {AppModuleFactoryLoader} from './linker/app_module_factory_loader';
export {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError} from './linker/compiler';
export {ComponentFactory, ComponentRef} from './linker/component_factory';
export {ComponentFactoryResolver, NoComponentFactoryError} from './linker/component_factory_resolver';
@@ -16,8 +14,10 @@ export {ComponentResolver} from './linker/component_resolver';
export {DynamicComponentLoader} from './linker/dynamic_component_loader';
export {ElementRef} from './linker/element_ref';
export {ExpressionChangedAfterItHasBeenCheckedException} from './linker/exceptions';
export {NgModuleFactory, NgModuleRef} from './linker/ng_module_factory';
export {NgModuleFactoryLoader} from './linker/ng_module_factory_loader';
export {QueryList} from './linker/query_list';
export {SystemJsAppModuleLoader} from './linker/system_js_app_module_factory_loader';
export {SystemJsNgModuleLoader} from './linker/system_js_ng_module_factory_loader';
export {SystemJsCmpFactoryResolver, SystemJsComponentResolver} from './linker/systemjs_component_resolver';
export {TemplateRef} from './linker/template_ref';
export {ViewContainerRef} from './linker/view_container_ref';
+25 -56
View File
@@ -6,14 +6,15 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injector} from '../di';
import {Injector, OpaqueToken} from '../di';
import {BaseException} from '../facade/exceptions';
import {ConcreteType, Type, stringify} from '../facade/lang';
import {ViewEncapsulation} from '../metadata';
import {AppModuleMetadata} from '../metadata/app_module';
import {NgModuleMetadata} from '../metadata/ng_module';
import {AppModuleFactory} from './app_module_factory';
import {ComponentFactory} from './component_factory';
import {ComponentResolver} from './component_resolver';
import {NgModuleFactory} from './ng_module_factory';
/**
@@ -32,14 +33,16 @@ export class ComponentStillLoadingError extends BaseException {
* to create {@link ComponentFactory}s, which
* can later be used to create and render a Component instance.
*
* Each `@AppModule` provides an own `Compiler` to its injector,
* that will use the directives/pipes of the app module for compilation
* Each `@NgModule` provides an own `Compiler` to its injector,
* that will use the directives/pipes of the ng module for compilation
* of components.
* @stable
*/
export class Compiler {
/**
* Returns the injector with which the compiler has been created.
*
* @internal
*/
get injector(): Injector {
throw new BaseException(`Runtime compiler is not loaded. Tried to read the injector.`);
@@ -48,7 +51,8 @@ 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>, ngModule: Type = null):
Promise<ComponentFactory<T>> {
throw new BaseException(
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
}
@@ -56,23 +60,21 @@ export class Compiler {
* Compiles the given component. All templates have to be either inline or compiled via
* `compileComponentAsync` before. Otherwise throws a {@link ComponentStillLoadingError}.
*/
compileComponentSync<T>(component: ConcreteType<T>): ComponentFactory<T> {
compileComponentSync<T>(component: ConcreteType<T>, ngModule: Type = null): 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`
* Compiles the given NgModule. All templates of the components listed in `precompile`
* have to be either inline or compiled before via `compileComponentAsync` /
* `compileAppModuleAsync`. Otherwise throws a {@link ComponentStillLoadingError}.
* `compileModuleAsync`. Otherwise throws a {@link ComponentStillLoadingError}.
*/
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
AppModuleFactory<T> {
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<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>> {
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
throw new BaseException(
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
}
@@ -83,7 +85,7 @@ export class Compiler {
clearCache(): void {}
/**
* Clears the cache for the given component/appModule.
* Clears the cache for the given component/ngModule.
*/
clearCacheFor(type: Type) {}
}
@@ -98,8 +100,14 @@ export type CompilerOptions = {
useJit?: boolean,
defaultEncapsulation?: ViewEncapsulation,
providers?: any[],
deprecatedAppProviders?: any[]
}
};
/**
* Token to provide CompilerOptions in the platform injector.
*
* @experimental
*/
export const CompilerOptions = new OpaqueToken('compilerOptions');
/**
* A factory for creating a Compiler
@@ -107,44 +115,5 @@ export type CompilerOptions = {
* @experimental
*/
export abstract class CompilerFactory {
static mergeOptions(defaultOptions: CompilerOptions = {}, newOptions: CompilerOptions = {}):
CompilerOptions {
return {
useDebug: _firstDefined(newOptions.useDebug, defaultOptions.useDebug),
useJit: _firstDefined(newOptions.useJit, defaultOptions.useJit),
defaultEncapsulation:
_firstDefined(newOptions.defaultEncapsulation, defaultOptions.defaultEncapsulation),
providers: _mergeArrays(defaultOptions.providers, newOptions.providers),
deprecatedAppProviders:
_mergeArrays(defaultOptions.deprecatedAppProviders, newOptions.deprecatedAppProviders)
};
}
withDefaults(options: CompilerOptions = {}): CompilerFactory {
return new _DefaultApplyingCompilerFactory(this, options);
}
abstract createCompiler(options?: CompilerOptions): Compiler;
}
class _DefaultApplyingCompilerFactory extends CompilerFactory {
constructor(private _delegate: CompilerFactory, private _options: CompilerOptions) { super(); }
createCompiler(options: CompilerOptions = {}): Compiler {
return this._delegate.createCompiler(CompilerFactory.mergeOptions(this._options, options));
}
}
function _firstDefined<T>(...args: T[]): T {
for (var i = 0; i < args.length; i++) {
if (args[i] !== undefined) {
return args[i];
}
}
return undefined;
}
function _mergeArrays(...parts: any[][]): any[] {
let result: any[] = [];
parts.forEach((part) => result.push.apply(result, part));
return result;
abstract createCompiler(options?: CompilerOptions[]): Compiler;
}
@@ -6,12 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Console} from '../console';
import {Injectable} from '../di/decorators';
import {PromiseWrapper} from '../facade/async';
import {BaseException} from '../facade/exceptions';
import {Type, isBlank, isString, stringify} from '../facade/lang';
import {reflector} from '../reflection/reflection';
import {Type} from '../facade/lang';
import {ComponentFactory} from './component_factory';
/**
@@ -19,43 +14,17 @@ import {ComponentFactory} from './component_factory';
* can later be used to create and render a Component instance.
*
* @deprecated Use {@link ComponentFactoryResolver} together with {@link
* AppModule}.precompile}/{@link Component}.precompile or
* NgModule}.precompile}/{@link Component}.precompile or
* {@link ANALYZE_FOR_PRECOMPILE} provider for dynamic component creation.
* Use {@link AppModuleFactoryLoader} for lazy loading.
* Use {@link NgModuleFactoryLoader} for lazy loading.
*/
export abstract class ComponentResolver {
static DynamicCompilationDeprecationMsg =
'ComponentResolver is deprecated for dynamic compilation. Use ComponentFactoryResolver together with @AppModule/@Component.precompile or ANALYZE_FOR_PRECOMPILE provider instead.';
'ComponentResolver is deprecated for dynamic compilation. Use ComponentFactoryResolver together with @NgModule/@Component.precompile or ANALYZE_FOR_PRECOMPILE provider instead. For runtime compile only, you can also use Compiler.compileComponentSync/Async.';
static LazyLoadingDeprecationMsg =
'ComponentResolver is deprecated for lazy loading. Use AppModuleFactoryLoader instead.';
'ComponentResolver is deprecated for lazy loading. Use NgModuleFactoryLoader instead.';
abstract resolveComponent(component: Type|string): Promise<ComponentFactory<any>>;
abstract clearCache(): void;
}
function _isComponentFactory(type: any): boolean {
return type instanceof ComponentFactory;
}
@Injectable()
export class ReflectorComponentResolver extends ComponentResolver {
constructor(private _console: Console) { super(); }
resolveComponent(component: Type|string): Promise<ComponentFactory<any>> {
if (isString(component)) {
return PromiseWrapper.reject(
new BaseException(`Cannot resolve component using '${component}'.`), null);
}
this._console.warn(ComponentResolver.DynamicCompilationDeprecationMsg);
var metadatas = reflector.annotations(<Type>component);
var componentFactory = metadatas.find(_isComponentFactory);
if (isBlank(componentFactory)) {
throw new BaseException(`No precompiled component ${stringify(component)} found`);
}
return PromiseWrapper.resolve(componentFactory);
}
clearCache() {}
}
@@ -8,13 +8,15 @@
import {Injectable, Injector, ReflectiveInjector, ResolvedReflectiveProvider} from '../di';
import {Type, isPresent} from '../facade/lang';
import {Compiler} from './compiler';
import {ComponentRef} from './component_factory';
import {ComponentResolver} from './component_resolver';
import {ViewContainerRef} from './view_container_ref';
/**
* Use ComponentResolver and ViewContainerRef directly.
* Use ComponentFactoryResolver and ViewContainerRef directly.
*
* @deprecated
*/
@@ -119,12 +121,12 @@ export abstract class DynamicComponentLoader {
@Injectable()
export class DynamicComponentLoader_ extends DynamicComponentLoader {
constructor(private _compiler: ComponentResolver) { super(); }
constructor(private _compiler: Compiler) { super(); }
loadAsRoot(
type: Type, overrideSelectorOrNode: string|any, injector: Injector, onDispose?: () => void,
projectableNodes?: any[][]): Promise<ComponentRef<any>> {
return this._compiler.resolveComponent(type).then(componentFactory => {
return this._compiler.compileComponentAsync(<any>type).then(componentFactory => {
var componentRef = componentFactory.create(
injector, projectableNodes,
isPresent(overrideSelectorOrNode) ? overrideSelectorOrNode : componentFactory.selector);
@@ -138,7 +140,7 @@ export class DynamicComponentLoader_ extends DynamicComponentLoader {
loadNextToLocation(
type: Type, location: ViewContainerRef, providers: ResolvedReflectiveProvider[] = null,
projectableNodes: any[][] = null): Promise<ComponentRef<any>> {
return this._compiler.resolveComponent(type).then(componentFactory => {
return this._compiler.compileComponentAsync(<any>type).then(componentFactory => {
var contextInjector = location.parentInjector;
var childInjector = isPresent(providers) && providers.length > 0 ?
ReflectiveInjector.fromResolvedProviders(providers, contextInjector) :
@@ -14,15 +14,16 @@ import {CodegenComponentFactoryResolver, ComponentFactoryResolver} from './compo
/**
* Represents an instance of an AppModule created via a {@link AppModuleFactory}.
* Represents an instance of an NgModule created via a {@link NgModuleFactory}.
*
* `AppModuleRef` provides access to the AppModule Instance as well other objects related to this
* AppModule Instance.
* @stable
* `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
* NgModule Instance.
*
* @experimental
*/
export abstract class AppModuleRef<T> {
export abstract class NgModuleRef<T> {
/**
* The injector that contains all of the providers of the AppModule.
* The injector that contains all of the providers of the NgModule.
*/
get injector(): Injector { return unimplemented(); }
@@ -33,22 +34,22 @@ export abstract class AppModuleRef<T> {
get componentFactoryResolver(): ComponentFactoryResolver { return unimplemented(); }
/**
* The AppModule instance.
* The NgModule instance.
*/
get instance(): T { return unimplemented(); }
}
/**
* @stable
* @experimental
*/
export class AppModuleFactory<T> {
export class NgModuleFactory<T> {
constructor(
private _injectorClass: {new (parentInjector: Injector): AppModuleInjector<T>},
private _injectorClass: {new (parentInjector: Injector): NgModuleInjector<T>},
private _moduleype: ConcreteType<T>) {}
get moduleType(): ConcreteType<T> { return this._moduleype; }
create(parentInjector: Injector = null): AppModuleRef<T> {
create(parentInjector: Injector): NgModuleRef<T> {
if (!parentInjector) {
parentInjector = Injector.NULL;
}
@@ -60,9 +61,9 @@ export class AppModuleFactory<T> {
const _UNDEFINED = new Object();
export abstract class AppModuleInjector<T> extends CodegenComponentFactoryResolver implements
export abstract class NgModuleInjector<T> extends CodegenComponentFactoryResolver implements
Injector,
AppModuleRef<T> {
NgModuleRef<T> {
public instance: T;
constructor(public parent: Injector, factories: ComponentFactory<any>[]) {
@@ -6,12 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AppModuleFactory} from './app_module_factory';
import {NgModuleFactory} from './ng_module_factory';
/**
* Used to load app moduled factories.
* Used to load ng moduled factories.
* @experimental
*/
export abstract class AppModuleFactoryLoader {
abstract load(path: string): Promise<AppModuleFactory<any>>;
}
export abstract class NgModuleFactoryLoader {
abstract load(path: string): Promise<NgModuleFactory<any>>;
}
@@ -10,9 +10,9 @@
import {Injectable, Optional} from '../di';
import {global} from '../facade/lang';
import {AppModuleFactory} from './app_module_factory';
import {AppModuleFactoryLoader} from './app_module_factory_loader';
import {Compiler} from './compiler';
import {NgModuleFactory} from './ng_module_factory';
import {NgModuleFactoryLoader} from './ng_module_factory_loader';
const _SEPARATOR = '#';
@@ -20,18 +20,18 @@ const FACTORY_MODULE_SUFFIX = '.ngfactory';
const FACTORY_CLASS_SUFFIX = 'NgFactory';
/**
* AppModuleFactoryLoader that uses SystemJS to load AppModuleFactory
* NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
* @experimental
*/
@Injectable()
export class SystemJsAppModuleLoader implements AppModuleFactoryLoader {
export class SystemJsNgModuleLoader implements NgModuleFactoryLoader {
constructor(@Optional() private _compiler: Compiler) {}
load(path: string): Promise<AppModuleFactory<any>> {
load(path: string): Promise<NgModuleFactory<any>> {
return this._compiler ? this.loadAndCompile(path) : this.loadFactory(path);
}
private loadAndCompile(path: string): Promise<AppModuleFactory<any>> {
private loadAndCompile(path: string): Promise<NgModuleFactory<any>> {
let [module, exportName] = path.split(_SEPARATOR);
if (exportName === undefined) exportName = 'default';
@@ -39,10 +39,10 @@ export class SystemJsAppModuleLoader implements AppModuleFactoryLoader {
.System.import(module)
.then((module: any) => module[exportName])
.then((type: any) => checkNotEmpty(type, module, exportName))
.then((type: any) => this._compiler.compileAppModuleAsync(type));
.then((type: any) => this._compiler.compileModuleAsync(type));
}
private loadFactory(path: string): Promise<AppModuleFactory<any>> {
private loadFactory(path: string): Promise<NgModuleFactory<any>> {
let [module, exportName] = path.split(_SEPARATOR);
if (exportName === undefined) exportName = 'default';
@@ -58,4 +58,4 @@ function checkNotEmpty(value: any, modulePath: string, exportName: string): any
throw new Error(`Cannot find '${exportName}' in '${modulePath}'`);
}
return value;
}
}
@@ -18,9 +18,9 @@ const _SEPARATOR = '#';
/**
* Component resolver that can load components lazily
*
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsAppModuleLoader} to lazy
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsNgModuleLoader} to lazy
* load
* {@link AppModuleFactory}s instead.
* {@link NgModuleFactory}s instead.
*/
@Injectable()
export class SystemJsComponentResolver implements ComponentResolver {
@@ -53,9 +53,9 @@ const FACTORY_CLASS_SUFFIX = 'NgFactory';
/**
* Component resolver that can load component factories lazily
*
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsAppModuleLoader}
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsNgModuleLoader}
* to lazy
* load {@link AppModuleFactory}s instead.
* load {@link NgModuleFactory}s instead.
*/
@Injectable()
export class SystemJsCmpFactoryResolver implements ComponentResolver {
+24 -24
View File
@@ -14,15 +14,15 @@
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 {NgModuleMetadata} from './metadata/ng_module';
import {ViewEncapsulation, ViewMetadata} from './metadata/view';
export {AppModuleMetadata} from './metadata/app_module';
export {ANALYZE_FOR_PRECOMPILE, 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';
export {NgModuleMetadata} from './metadata/ng_module';
export {ViewEncapsulation, ViewMetadata} from './metadata/view';
import {makeDecorator, makeParamDecorator, makePropDecorator, TypeDecorator,} from './util/decorators';
@@ -86,13 +86,13 @@ export interface ViewDecorator extends TypeDecorator {
}
/**
* Interface for the {@link AppModuleMetadata} decorator function.
* Interface for the {@link NgModuleMetadata} decorator function.
*
* See {@link AppModuleMetadataFactory}.
* See {@link NgModuleMetadataFactory}.
*
* @stable
*/
export interface AppModuleDecorator extends TypeDecorator {}
export interface NgModuleDecorator extends TypeDecorator {}
/**
@@ -490,25 +490,25 @@ export interface HostListenerMetadataFactory {
}
/**
* {@link AppModuleMetadata} factory for creating annotations, decorators or DSL.
* {@link NgModuleMetadata} factory for creating annotations, decorators or DSL.
*
* @stable
* @experimental
*/
export interface AppModuleMetadataFactory {
(obj: {
export interface NgModuleMetadataFactory {
(obj?: {
providers?: any[],
directives?: Array<Type|any[]>,
pipes?: Array<Type|any[]>,
precompile?: Array<Type|any[]>,
modules?: Array<Type|any[]>,
}): AppModuleDecorator;
new (obj: {
declarations?: Array<Type|any[]>,
imports?: Array<Type|any[]>,
exports?: Array<Type|any[]>,
precompile?: Array<Type|any[]>
}): NgModuleDecorator;
new (obj?: {
providers?: any[],
directives?: Array<Type|any[]>,
pipes?: Array<Type|any[]>,
precompile?: Array<Type|any[]>,
modules?: Array<Type|any[]>,
}): AppModuleMetadata;
declarations?: Array<Type|any[]>,
imports?: Array<Type|any[]>,
exports?: Array<Type|any[]>,
precompile?: Array<Type|any[]>
}): NgModuleMetadata;
}
// TODO(alexeagle): remove the duplication of this doc. It is copied from ComponentMetadata.
@@ -1537,9 +1537,9 @@ export var HostBinding: HostBindingMetadataFactory = makePropDecorator(HostBindi
export var HostListener: HostListenerMetadataFactory = makePropDecorator(HostListenerMetadata);
/**
* Declares an app module.
* @stable
* Declares an ng module.
* @experimental
* @Annotation
*/
export var AppModule: AppModuleMetadataFactory =
<AppModuleMetadataFactory>makeDecorator(AppModuleMetadata);
export var NgModule: NgModuleMetadataFactory =
<NgModuleMetadataFactory>makeDecorator(NgModuleMetadata);
+3 -3
View File
@@ -13,13 +13,13 @@ import {StringWrapper, Type, isString, stringify} from '../facade/lang';
/**
* This token can be used to create a virtual provider that will populate the
* `precompile` fields of components and app modules based on its `useValue`.
* `precompile` fields of components and ng modules based on its `useValue`.
* All components that are referenced in the `useValue` value (either directly
* or in a nested array or map) will be added to the `precompile` property.
*
* ### Example
* The following example shows how the router can populate the `precompile`
* field of an AppModule based on the router configuration which refers
* field of an NgModule based on the router configuration which refers
* to components.
*
* ```typescript
@@ -37,7 +37,7 @@ import {StringWrapper, Type, isString, stringify} from '../facade/lang';
* {path: /teams', component: TeamsComp}
* ];
*
* @AppModule({
* @NgModule({
* providers: [provideRoutes(routes)]
* })
* class ModuleWithRoutes {}
@@ -10,10 +10,10 @@ import {InjectableMetadata} from '../di/metadata';
import {Type} from '../facade/lang';
/**
* Declares an Application Module.
* @stable
* Declares an Angular Module.
* @experimental
*/
export class AppModuleMetadata extends InjectableMetadata {
export class NgModuleMetadata extends InjectableMetadata {
/**
* Defines the set of injectable objects that are available in the injector
* of this module.
@@ -29,7 +29,7 @@ export class AppModuleMetadata extends InjectableMetadata {
* }
* }
*
* @AppModule({
* @NgModule({
* providers: [
* Greeter
* ]
@@ -48,36 +48,52 @@ export class AppModuleMetadata extends InjectableMetadata {
/**
* Specifies a list of directives that can be used within the template
* of any component that is part of this application module.
* Specifies a list of directives/pipes that belong to this module.
*
* ### Example
*
* ```javascript
* @AppModule({
* directives: [NgFor]
* @NgModule({
* declarations: [NgFor]
* })
* class MyAppModule {
* class CommonModule {
* }
* ```
*/
directives: Array<Type|any[]>;
declarations: 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.
* Specifies a list of modules whose exported directives/pipes
* should be available to templates in this module.
*
* ### Example
*
* ```javascript
* @AppModule({
* pipes: [SomePipe]
* @NgModule({
* imports: [CommonModule]
* })
* class MyAppModule {
* class MainModule {
* }
* ```
*/
pipes: Array<Type|any[]>;
imports: Array<Type|any[]>;
/**
* Specifies a list of directives/pipes/module that can be used within the template
* of any component that is part of an angular module
* that imports this angular module.
*
* ### Example
*
* ```javascript
* @NgModule({
* exports: [NgFor]
* })
* class CommonModule {
* }
* ```
*/
exports: Array<Type|any[]>;
/**
* Defines the components that should be precompiled as well when
@@ -87,27 +103,18 @@ export class AppModuleMetadata extends InjectableMetadata {
*/
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}: {
constructor({providers, declarations, imports, exports, precompile}: {
providers?: any[],
directives?: Array<Type|any[]>,
pipes?: Array<Type|any[]>,
precompile?: Array<Type|any[]>,
modules?: Array<Type|any[]>
declarations?: Array<Type|any[]>,
imports?: Array<Type|any[]>,
exports?: Array<Type|any[]>,
precompile?: Array<Type|any[]>
} = {}) {
super();
this._providers = providers;
this.directives = directives;
this.pipes = pipes;
this.declarations = declarations;
this.imports = imports;
this.exports = exports;
this.precompile = precompile;
this.modules = modules;
}
}
@@ -8,7 +8,7 @@
import {Type} from '../src/facade/lang';
import {PLATFORM_CORE_PROVIDERS} from './application_ref';
import {PlatformRef, PlatformRef_, createPlatformFactory} from './application_ref';
import {Console} from './console';
import {Provider} from './di';
import {Reflector, reflector} from './reflection/reflection';
@@ -21,13 +21,22 @@ function _reflector(): Reflector {
var __unused: Type; // prevent missing use Dart warning.
const _CORE_PLATFORM_PROVIDERS: Array<any|Type|Provider|any[]> = [
PlatformRef_, {provide: PlatformRef, useExisting: PlatformRef_},
{provide: Reflector, useFactory: _reflector, deps: []},
{provide: ReflectorReader, useExisting: Reflector}, TestabilityRegistry, Console
];
/**
* A default set of providers which should be included in any Angular platform.
* This platform has to be included in any other platform
*
* @experimental
*/
export const PLATFORM_COMMON_PROVIDERS: Array<any|Type|Provider|any[]> = /*@ts2dart_const*/[
PLATFORM_CORE_PROVIDERS,
/*@ts2dart_Provider*/ {provide: Reflector, useFactory: _reflector, deps: []},
/*@ts2dart_Provider*/ {provide: ReflectorReader, useExisting: Reflector}, TestabilityRegistry,
Console
];
export const corePlatform = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);
/**
* A default set of providers which should be included in any Angular platform.
*
* @deprecated Create platforms via `createPlatformFactory(corePlatform, ...) instead!
*/
export const PLATFORM_COMMON_PROVIDERS = _CORE_PLATFORM_PROVIDERS;
@@ -34,7 +34,7 @@ import {OpaqueToken} from './di';
* ```
*
* @deprecated Providing platform directives via a provider is deprecated. Provide platform
* directives via an {@link AppModule} instead.
* directives via an {@link NgModule} instead.
*/
export const PLATFORM_DIRECTIVES: OpaqueToken =
/*@ts2dart_const*/ new OpaqueToken('Platform Directives');
@@ -63,6 +63,6 @@ export const PLATFORM_DIRECTIVES: OpaqueToken =
* ```
*
* @deprecated Providing platform pipes via a provider is deprecated. Provide platform pipes via an
* {@link AppModule} instead.
* {@link NgModule} instead.
*/
export const PLATFORM_PIPES: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('Platform Pipes');
export const PLATFORM_PIPES: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('Platform Pipes');