feat(router): register NgModuleFactory objects. (#11211)

When lazily loading code, users need to be able to get hold of the
NgModuleFactory. For SystemJS environments, the SystemJS registry serves
this purpose. However other environments, such as modules compiled with
Closure compiler, do not expose exports object or a path based registry.

For these environments, `@NgModule` objects can include an identifier, and
the loading code can then pass `loadModule(id).then(() =>
getNgModule(id))` to the router.
This commit is contained in:
Martin Probst
2016-09-01 13:46:08 -07:00
committed by GitHub
parent c9e5b599e4
commit ebc8e808a9
11 changed files with 99 additions and 8 deletions

View File

@ -525,13 +525,14 @@ export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
importedModules: CompileNgModuleMetadata[];
exportedModules: CompileNgModuleMetadata[];
schemas: SchemaMetadata[];
id: string;
transitiveModule: TransitiveCompileNgModuleMetadata;
constructor(
{type, providers, declaredDirectives, exportedDirectives, declaredPipes, exportedPipes,
entryComponents, bootstrapComponents, importedModules, exportedModules, schemas,
transitiveModule}: {
transitiveModule, id}: {
type?: CompileTypeMetadata,
providers?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
@ -544,7 +545,8 @@ export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
importedModules?: CompileNgModuleMetadata[],
exportedModules?: CompileNgModuleMetadata[],
transitiveModule?: TransitiveCompileNgModuleMetadata,
schemas?: SchemaMetadata[]
schemas?: SchemaMetadata[],
id?: string
} = {}) {
this.type = type;
this.declaredDirectives = _normalizeArray(declaredDirectives);
@ -557,6 +559,7 @@ export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
this.importedModules = _normalizeArray(importedModules);
this.exportedModules = _normalizeArray(exportedModules);
this.schemas = _normalizeArray(schemas);
this.id = id;
this.transitiveModule = transitiveModule;
}

View File

@ -9,7 +9,7 @@
import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, LOCALE_ID as LOCALE_ID_, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT as TRANSLATIONS_FORMAT_, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
import {AnimationGroupPlayer, AnimationKeyframe, AnimationOutput, AnimationSequencePlayer, AnimationStyles, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes, castByValue, checkBinding, clearStyles, collectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, reflector, renderStyles} from './private_import_core';
import {AnimationGroupPlayer, AnimationKeyframe, AnimationOutput, AnimationSequencePlayer, AnimationStyles, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes, castByValue, checkBinding, clearStyles, collectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, reflector, registerModuleFactory, renderStyles} from './private_import_core';
import {assetUrl} from './util';
var APP_VIEW_MODULE_URL = assetUrl('core', 'linker/view');
@ -107,6 +107,11 @@ export class Identifiers {
runtime: NgModuleInjector,
moduleUrl: assetUrl('core', 'linker/ng_module_factory')
};
static RegisterModuleFactoryFn: IdentifierSpec = {
name: 'registerModuleFactory',
runtime: registerModuleFactory,
moduleUrl: assetUrl('core', 'linker/ng_module_factory_loader')
};
static ValueUnwrapper:
IdentifierSpec = {name: 'ValueUnwrapper', moduleUrl: CD_MODULE_URL, runtime: ValueUnwrapper};
static Injector: IdentifierSpec = {

View File

@ -328,7 +328,8 @@ export class CompileMetadataResolver {
exportedPipes: exportedPipes,
importedModules: importedModules,
exportedModules: exportedModules,
transitiveModule: transitiveModule
transitiveModule: transitiveModule,
id: meta.id,
});
transitiveModule.modules.push(compileMeta);
this._verifyModule(compileMeta);

View File

@ -69,8 +69,16 @@ export class NgModuleCompiler {
[o.importType(ngModuleMeta.type)], [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]);
return new NgModuleCompileResult(
[injectorClass, ngModuleFactoryStmt], ngModuleFactoryVar, deps);
let stmts: o.Statement[] = [injectorClass, ngModuleFactoryStmt];
if (ngModuleMeta.id) {
let registerFactoryStmt =
o.importExpr(resolveIdentifier(Identifiers.RegisterModuleFactoryFn))
.callFn([o.literal(ngModuleMeta.id), o.variable(ngModuleFactoryVar)])
.toStmt();
stmts.push(registerFactoryStmt);
}
return new NgModuleCompileResult(stmts, ngModuleFactoryVar, deps);
}
}

View File

@ -25,6 +25,7 @@ export const CodegenComponentFactoryResolver: typeof r.CodegenComponentFactoryRe
export const AppView: typeof r.AppView = r.AppView;
export const DebugAppView: typeof r.DebugAppView = r.DebugAppView;
export const NgModuleInjector: typeof r.NgModuleInjector = r.NgModuleInjector;
export const registerModuleFactory: typeof r.registerModuleFactory = r.registerModuleFactory;
export type ViewType = typeof r._ViewType;
export const ViewType: typeof r.ViewType = r.ViewType;
export const MAX_INTERPOLATION_VALUES: typeof r.MAX_INTERPOLATION_VALUES =