refactor: use view engine also for NgModuleFactory
s (#16658)
* refactor(core): provide error message in stack for reflective DI Fixes #16355 * fix(compiler): make AOT work with `noUnusedParameters` Fixes #15532 * refactor: use view engine also for `NgModuleFactory`s This is a prerequisite for being able to mock providers in AOTed code later on.
This commit is contained in:
@ -10,7 +10,7 @@ import {RendererType2} from '../render/api';
|
||||
import {SecurityContext} from '../security';
|
||||
|
||||
import {BindingDef, BindingFlags, ElementData, ElementHandleEventFn, NodeDef, NodeFlags, OutputDef, OutputType, QueryValueType, ViewData, ViewDefinitionFactory, asElementData} from './types';
|
||||
import {NOOP, calcBindingFlags, checkAndUpdateBinding, dispatchEvent, elementEventFullName, getParentRenderElement, resolveRendererType2, resolveViewDefinition, splitMatchedQueriesDsl, splitNamespace} from './util';
|
||||
import {NOOP, calcBindingFlags, checkAndUpdateBinding, dispatchEvent, elementEventFullName, getParentRenderElement, resolveDefinition, resolveRendererType2, splitMatchedQueriesDsl, splitNamespace} from './util';
|
||||
|
||||
export function anchorDef(
|
||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
||||
@ -18,7 +18,7 @@ export function anchorDef(
|
||||
templateFactory?: ViewDefinitionFactory): NodeDef {
|
||||
flags |= NodeFlags.TypeElement;
|
||||
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
||||
const template = templateFactory ? resolveViewDefinition(templateFactory) : null;
|
||||
const template = templateFactory ? resolveDefinition(templateFactory) : null;
|
||||
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
|
@ -8,13 +8,15 @@
|
||||
|
||||
export {anchorDef, elementDef} from './element';
|
||||
export {ngContentDef} from './ng_content';
|
||||
export {moduleDef, moduleProvideDef} from './ng_module';
|
||||
export {directiveDef, pipeDef, providerDef} from './provider';
|
||||
export {pureArrayDef, pureObjectDef, purePipeDef} from './pure_expression';
|
||||
export {queryDef} from './query';
|
||||
export {ViewRef_, createComponentFactory, getComponentViewDefinitionFactory, nodeValue} from './refs';
|
||||
export {createNgModuleFactory} from './refs';
|
||||
export {initServicesIfNeeded} from './services';
|
||||
export {textDef} from './text';
|
||||
export {EMPTY_ARRAY, EMPTY_MAP, createRendererType2, elementEventFullName, inlineInterpolate, interpolate, rootRenderNodes, unwrapValue} from './util';
|
||||
export {EMPTY_ARRAY, EMPTY_MAP, createRendererType2, elementEventFullName, inlineInterpolate, interpolate, rootRenderNodes, tokenKey, unwrapValue} from './util';
|
||||
export {viewDef} from './view';
|
||||
export {attachEmbeddedView, detachEmbeddedView, moveEmbeddedView} from './view_attach';
|
||||
|
||||
|
184
packages/core/src/view/ng_module.ts
Normal file
184
packages/core/src/view/ng_module.ts
Normal file
@ -0,0 +1,184 @@
|
||||
/**
|
||||
* @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 {NgModuleRef} from '../linker/ng_module_factory';
|
||||
|
||||
import {DepDef, DepFlags, NgModuleData, NgModuleDefinition, NgModuleDefinitionFactory, NgModuleProviderDef, NodeFlags} from './types';
|
||||
import {tokenKey} from './util';
|
||||
|
||||
const NOT_CREATED = new Object();
|
||||
|
||||
const InjectorRefTokenKey = tokenKey(Injector);
|
||||
const NgModuleRefTokenKey = tokenKey(NgModuleRef);
|
||||
|
||||
export function moduleProvideDef(
|
||||
flags: NodeFlags, token: any, value: any,
|
||||
deps: ([DepFlags, any] | any)[]): NgModuleProviderDef {
|
||||
const depDefs: DepDef[] = deps.map(value => {
|
||||
let token: any;
|
||||
let flags: DepFlags;
|
||||
if (Array.isArray(value)) {
|
||||
[flags, token] = value;
|
||||
} else {
|
||||
flags = DepFlags.None;
|
||||
token = value;
|
||||
}
|
||||
return {flags, token, tokenKey: tokenKey(token)};
|
||||
});
|
||||
return {
|
||||
// will bet set by the module definition
|
||||
index: -1,
|
||||
deps: depDefs, flags, token, value
|
||||
};
|
||||
}
|
||||
|
||||
export function moduleDef(providers: NgModuleProviderDef[]): NgModuleDefinition {
|
||||
const providersByKey: {[key: string]: NgModuleProviderDef} = {};
|
||||
for (let i = 0; i < providers.length; i++) {
|
||||
const provider = providers[i];
|
||||
provider.index = i;
|
||||
providersByKey[tokenKey(provider.token)] = provider;
|
||||
}
|
||||
return {
|
||||
// Will be filled later...
|
||||
factory: null,
|
||||
providersByKey,
|
||||
providers
|
||||
};
|
||||
}
|
||||
|
||||
export function initNgModule(data: NgModuleData) {
|
||||
const def = data._def;
|
||||
const providers = data._providers = new Array(def.providers.length);
|
||||
for (let i = 0; i < def.providers.length; i++) {
|
||||
const provDef = def.providers[i];
|
||||
providers[i] = provDef.flags & NodeFlags.LazyProvider ? NOT_CREATED :
|
||||
_createProviderInstance(data, provDef);
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveNgModuleDep(
|
||||
data: NgModuleData, depDef: DepDef, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any {
|
||||
if (depDef.flags & DepFlags.Value) {
|
||||
return depDef.token;
|
||||
}
|
||||
if (depDef.flags & DepFlags.Optional) {
|
||||
notFoundValue = null;
|
||||
}
|
||||
if (depDef.flags & DepFlags.SkipSelf) {
|
||||
return data._parent.get(depDef.token, notFoundValue);
|
||||
}
|
||||
const tokenKey = depDef.tokenKey;
|
||||
switch (tokenKey) {
|
||||
case InjectorRefTokenKey:
|
||||
case NgModuleRefTokenKey:
|
||||
return data;
|
||||
}
|
||||
const providerDef = data._def.providersByKey[tokenKey];
|
||||
if (providerDef) {
|
||||
let providerInstance = data._providers[providerDef.index];
|
||||
if (providerInstance === NOT_CREATED) {
|
||||
providerInstance = data._providers[providerDef.index] =
|
||||
_createProviderInstance(data, providerDef);
|
||||
}
|
||||
return providerInstance;
|
||||
}
|
||||
return data._parent.get(depDef.token, notFoundValue);
|
||||
}
|
||||
|
||||
|
||||
function _createProviderInstance(ngModule: NgModuleData, providerDef: NgModuleProviderDef): any {
|
||||
let injectable: any;
|
||||
switch (providerDef.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypeClassProvider:
|
||||
injectable = _createClass(ngModule, providerDef !.value, providerDef !.deps);
|
||||
break;
|
||||
case NodeFlags.TypeFactoryProvider:
|
||||
injectable = _callFactory(ngModule, providerDef !.value, providerDef !.deps);
|
||||
break;
|
||||
case NodeFlags.TypeUseExistingProvider:
|
||||
injectable = resolveNgModuleDep(ngModule, providerDef !.deps[0]);
|
||||
break;
|
||||
case NodeFlags.TypeValueProvider:
|
||||
injectable = providerDef !.value;
|
||||
break;
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
function _createClass(ngModule: NgModuleData, ctor: any, deps: DepDef[]): any {
|
||||
const len = deps.length;
|
||||
let injectable: any;
|
||||
switch (len) {
|
||||
case 0:
|
||||
injectable = new ctor();
|
||||
break;
|
||||
case 1:
|
||||
injectable = new ctor(resolveNgModuleDep(ngModule, deps[0]));
|
||||
break;
|
||||
case 2:
|
||||
injectable =
|
||||
new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||
break;
|
||||
case 3:
|
||||
injectable = new ctor(
|
||||
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
||||
resolveNgModuleDep(ngModule, deps[2]));
|
||||
break;
|
||||
default:
|
||||
const depValues = new Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
|
||||
}
|
||||
injectable = new ctor(...depValues);
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
function _callFactory(ngModule: NgModuleData, factory: any, deps: DepDef[]): any {
|
||||
const len = deps.length;
|
||||
let injectable: any;
|
||||
switch (len) {
|
||||
case 0:
|
||||
injectable = factory();
|
||||
break;
|
||||
case 1:
|
||||
injectable = factory(resolveNgModuleDep(ngModule, deps[0]));
|
||||
break;
|
||||
case 2:
|
||||
injectable =
|
||||
factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||
break;
|
||||
case 3:
|
||||
injectable = factory(
|
||||
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
||||
resolveNgModuleDep(ngModule, deps[2]));
|
||||
break;
|
||||
default:
|
||||
const depValues = Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
|
||||
}
|
||||
injectable = factory(...depValues);
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
export function callNgModuleLifecycle(ngModule: NgModuleData, lifecycles: NodeFlags) {
|
||||
const def = ngModule._def;
|
||||
for (let i = 0; i < def.providers.length; i++) {
|
||||
const provDef = def.providers[i];
|
||||
if (provDef.flags & NodeFlags.OnDestroy) {
|
||||
const instance = ngModule._providers[i];
|
||||
if (instance && instance !== NOT_CREATED) {
|
||||
instance.ngOnDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -105,7 +105,7 @@ export function _def(
|
||||
ngContentIndex: -1, childCount, bindings,
|
||||
bindingFlags: calcBindingFlags(bindings), outputs,
|
||||
element: null,
|
||||
provider: {token, tokenKey: tokenKey(token), value, deps: depDefs},
|
||||
provider: {token, value, deps: depDefs},
|
||||
text: null,
|
||||
query: null,
|
||||
ngContent: null
|
||||
|
@ -8,20 +8,22 @@
|
||||
|
||||
import {ApplicationRef} from '../application_ref';
|
||||
import {ChangeDetectorRef} from '../change_detection/change_detection';
|
||||
import {Injector} from '../di';
|
||||
import {Injector} from '../di/injector';
|
||||
import {ComponentFactory, ComponentRef} from '../linker/component_factory';
|
||||
import {ComponentFactoryBoundToModule} from '../linker/component_factory_resolver';
|
||||
import {ComponentFactoryBoundToModule, ComponentFactoryResolver} from '../linker/component_factory_resolver';
|
||||
import {ElementRef} from '../linker/element_ref';
|
||||
import {NgModuleRef} from '../linker/ng_module_factory';
|
||||
import {InternalNgModuleRef, NgModuleFactory, NgModuleRef} from '../linker/ng_module_factory';
|
||||
import {TemplateRef} from '../linker/template_ref';
|
||||
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||
import {EmbeddedViewRef, InternalViewRef, ViewRef} from '../linker/view_ref';
|
||||
import {Renderer as RendererV1, Renderer2} from '../render/api';
|
||||
import {Type} from '../type';
|
||||
import {stringify} from '../util';
|
||||
import {VERSION} from '../version';
|
||||
|
||||
import {DepFlags, ElementData, NodeDef, NodeFlags, Services, TemplateData, ViewContainerData, ViewData, ViewDefinitionFactory, ViewState, asElementData, asProviderData, asTextData} from './types';
|
||||
import {markParentViewsForCheck, resolveViewDefinition, rootRenderNodes, splitNamespace, tokenKey, viewParentEl} from './util';
|
||||
import {callNgModuleLifecycle, initNgModule, resolveNgModuleDep} from './ng_module';
|
||||
import {DepFlags, ElementData, NgModuleData, NgModuleDefinition, NgModuleDefinitionFactory, NodeDef, NodeFlags, Services, TemplateData, ViewContainerData, ViewData, ViewDefinitionFactory, ViewState, asElementData, asProviderData, asTextData} from './types';
|
||||
import {markParentViewsForCheck, resolveDefinition, rootRenderNodes, splitNamespace, tokenKey, viewParentEl} from './util';
|
||||
import {attachEmbeddedView, detachEmbeddedView, moveEmbeddedView, renderDetachView} from './view_attach';
|
||||
|
||||
const EMPTY_CONTEXT = new Object();
|
||||
@ -41,6 +43,14 @@ export function getComponentViewDefinitionFactory(componentFactory: ComponentFac
|
||||
return (componentFactory as ComponentFactory_).viewDefFactory;
|
||||
}
|
||||
|
||||
// Attention: this function is called as top level function.
|
||||
// Putting any logic in here will destroy closure tree shaking!
|
||||
export function createNgModuleFactory(
|
||||
ngModuleType: Type<any>, bootstrapComponents: Type<any>[],
|
||||
defFactory: NgModuleDefinitionFactory): NgModuleFactory<any> {
|
||||
return new NgModuleFactory_(ngModuleType, bootstrapComponents, defFactory);
|
||||
}
|
||||
|
||||
class ComponentFactory_ extends ComponentFactory<any> {
|
||||
/**
|
||||
* @internal
|
||||
@ -85,7 +95,7 @@ class ComponentFactory_ extends ComponentFactory<any> {
|
||||
if (!ngModule) {
|
||||
throw new Error('ngModule should be provided');
|
||||
}
|
||||
const viewDef = resolveViewDefinition(this.viewDefFactory);
|
||||
const viewDef = resolveDefinition(this.viewDefFactory);
|
||||
const componentNodeIndex = viewDef.nodes[0].element !.componentProvider !.index;
|
||||
const view = Services.createRootView(
|
||||
injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
|
||||
@ -452,3 +462,57 @@ class RendererAdapter implements RendererV1 {
|
||||
|
||||
animate(): any { throw new Error('Renderer.animate is no longer supported!'); }
|
||||
}
|
||||
|
||||
|
||||
class NgModuleFactory_ extends NgModuleFactory<any> {
|
||||
constructor(
|
||||
private _moduleType: Type<any>, private _bootstrapComponents: Type<any>[],
|
||||
private _ngModuleDefFactory: NgModuleDefinitionFactory, ) {
|
||||
// Attention: this ctor is called as top level function.
|
||||
// Putting any logic in here will destroy closure tree shaking!
|
||||
super();
|
||||
}
|
||||
|
||||
get moduleType(): Type<any> { return this._moduleType; }
|
||||
|
||||
create(parentInjector: Injector|null): NgModuleRef<any> {
|
||||
const def = resolveDefinition(this._ngModuleDefFactory);
|
||||
return new NgModuleRef_(
|
||||
this._moduleType, parentInjector || Injector.NULL, this._bootstrapComponents, def);
|
||||
}
|
||||
}
|
||||
|
||||
class NgModuleRef_ implements NgModuleData, InternalNgModuleRef<any> {
|
||||
private _destroyListeners: (() => void)[] = [];
|
||||
private _destroyed: boolean = false;
|
||||
public _providers: any[];
|
||||
|
||||
constructor(
|
||||
private _moduleType: any, public _parent: Injector, public _bootstrapComponents: Type<any>[],
|
||||
public _def: NgModuleDefinition) {
|
||||
initNgModule(this);
|
||||
}
|
||||
|
||||
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any {
|
||||
return resolveNgModuleDep(
|
||||
this, {token: token, tokenKey: tokenKey(token), flags: DepFlags.None}, notFoundValue);
|
||||
}
|
||||
|
||||
get instance() { return this.get(this._moduleType); }
|
||||
|
||||
get componentFactoryResolver() { return this.get(ComponentFactoryResolver); }
|
||||
|
||||
get injector(): Injector { return this; }
|
||||
|
||||
destroy(): void {
|
||||
if (this._destroyed) {
|
||||
throw new Error(
|
||||
`The ng module ${stringify(this.instance.constructor)} has already been destroyed.`);
|
||||
}
|
||||
this._destroyed = true;
|
||||
callNgModuleLifecycle(this, NodeFlags.OnDestroy);
|
||||
this._destroyListeners.forEach((listener) => listener());
|
||||
}
|
||||
|
||||
onDestroy(callback: () => void): void { this._destroyListeners.push(callback); }
|
||||
}
|
||||
|
@ -19,8 +19,32 @@ import {Sanitizer, SecurityContext} from '../security';
|
||||
// Defs
|
||||
// -------------------------------------
|
||||
|
||||
export interface ViewDefinition {
|
||||
factory: ViewDefinitionFactory|null;
|
||||
/**
|
||||
* Factory for ViewDefinitions/NgModuleDefinitions.
|
||||
* We use a function so we can reexeute it in case an error happens and use the given logger
|
||||
* function to log the error from the definition of the node, which is shown in all browser
|
||||
* logs.
|
||||
*/
|
||||
export interface DefinitionFactory<D extends Definition<any>> { (logger: NodeLogger): D; }
|
||||
|
||||
/**
|
||||
* Function to call console.error at the right source location. This is an indirection
|
||||
* via another function as browser will log the location that actually called
|
||||
* `console.error`.
|
||||
*/
|
||||
export interface NodeLogger { (): () => void; }
|
||||
|
||||
export interface Definition<DF extends DefinitionFactory<any>> { factory: DF|null; }
|
||||
|
||||
export interface NgModuleDefinition extends Definition<NgModuleDefinitionFactory> {
|
||||
providers: NgModuleProviderDef[];
|
||||
providersByKey: {[tokenKey: string]: NgModuleProviderDef};
|
||||
}
|
||||
|
||||
export interface NgModuleDefinitionFactory extends DefinitionFactory<NgModuleDefinition> {}
|
||||
;
|
||||
|
||||
export interface ViewDefinition extends Definition<ViewDefinitionFactory> {
|
||||
flags: ViewFlags;
|
||||
updateDirectives: ViewUpdateFn;
|
||||
updateRenderer: ViewUpdateFn;
|
||||
@ -44,20 +68,8 @@ export interface ViewDefinition {
|
||||
nodeMatchedQueries: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for ViewDefinitions.
|
||||
* We use a function so we can reexeute it in case an error happens and use the given logger
|
||||
* function to log the error from the definition of the node, which is shown in all browser
|
||||
* logs.
|
||||
*/
|
||||
export interface ViewDefinitionFactory { (logger: NodeLogger): ViewDefinition; }
|
||||
export interface ViewDefinitionFactory extends DefinitionFactory<ViewDefinition> {}
|
||||
|
||||
/**
|
||||
* Function to call console.error at the right source location. This is an indirection
|
||||
* via another function as browser will log the location that actually called
|
||||
* `console.error`.
|
||||
*/
|
||||
export interface NodeLogger { (): () => void; }
|
||||
|
||||
export interface ViewUpdateFn { (check: NodeCheckFn, view: ViewData): void; }
|
||||
|
||||
@ -245,7 +257,14 @@ export interface ElementHandleEventFn { (view: ViewData, eventName: string, even
|
||||
|
||||
export interface ProviderDef {
|
||||
token: any;
|
||||
tokenKey: string;
|
||||
value: any;
|
||||
deps: DepDef[];
|
||||
}
|
||||
|
||||
export interface NgModuleProviderDef {
|
||||
flags: NodeFlags;
|
||||
index: number;
|
||||
token: any;
|
||||
value: any;
|
||||
deps: DepDef[];
|
||||
}
|
||||
@ -296,6 +315,14 @@ export interface NgContentDef {
|
||||
// Data
|
||||
// -------------------------------------
|
||||
|
||||
export interface NgModuleData extends Injector, NgModuleRef<any> {
|
||||
// Note: we are using the prefix _ as NgModuleData is an NgModuleRef and therefore directly
|
||||
// exposed to the user.
|
||||
_def: NgModuleDefinition;
|
||||
_parent: Injector;
|
||||
_providers: any[];
|
||||
}
|
||||
|
||||
/**
|
||||
* View instance data.
|
||||
* Attention: Adding fields to this is performance sensitive!
|
||||
@ -379,13 +406,20 @@ export interface ElementData {
|
||||
template: TemplateData;
|
||||
}
|
||||
|
||||
export interface ViewContainerData extends ViewContainerRef { _embeddedViews: ViewData[]; }
|
||||
export interface ViewContainerData extends ViewContainerRef {
|
||||
// Note: we are using the prefix _ as ViewContainerData is a ViewContainerRef and therefore
|
||||
// directly
|
||||
// exposed to the user.
|
||||
_embeddedViews: ViewData[];
|
||||
}
|
||||
|
||||
export interface TemplateData extends TemplateRef<any> {
|
||||
// views that have been created from the template
|
||||
// of this element,
|
||||
// but inserted into the embeddedViews of another element.
|
||||
// By default, this is undefined.
|
||||
// Note: we are using the prefix _ as TemplateData is a TemplateRef and therefore directly
|
||||
// exposed to the user.
|
||||
_projectedViews: ViewData[];
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import {RendererType2} from '../render/api';
|
||||
import {looseIdentical, stringify} from '../util';
|
||||
|
||||
import {expressionChangedAfterItHasBeenCheckedError} from './errors';
|
||||
import {BindingDef, BindingFlags, ElementData, NodeDef, NodeFlags, QueryValueType, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewState, asElementData, asTextData} from './types';
|
||||
import {BindingDef, BindingFlags, Definition, DefinitionFactory, ElementData, NodeDef, NodeFlags, QueryValueType, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewState, asElementData, asTextData} from './types';
|
||||
|
||||
export const NOOP: any = () => {};
|
||||
|
||||
@ -220,14 +220,14 @@ export function getParentRenderElement(view: ViewData, renderHost: any, def: Nod
|
||||
}
|
||||
}
|
||||
|
||||
const VIEW_DEFINITION_CACHE = new WeakMap<any, ViewDefinition>();
|
||||
const DEFINITION_CACHE = new WeakMap<any, Definition<any>>();
|
||||
|
||||
export function resolveViewDefinition(factory: ViewDefinitionFactory): ViewDefinition {
|
||||
let value: ViewDefinition = VIEW_DEFINITION_CACHE.get(factory) !;
|
||||
export function resolveDefinition<D extends Definition<any>>(factory: DefinitionFactory<D>): D {
|
||||
let value = DEFINITION_CACHE.get(factory) !as D;
|
||||
if (!value) {
|
||||
value = factory(() => NOOP);
|
||||
value.factory = factory;
|
||||
VIEW_DEFINITION_CACHE.set(factory, value);
|
||||
DEFINITION_CACHE.set(factory, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import {checkAndUpdateQuery, createQuery} from './query';
|
||||
import {createTemplateData, createViewContainerData} from './refs';
|
||||
import {checkAndUpdateTextDynamic, checkAndUpdateTextInline, createText} from './text';
|
||||
import {ArgumentType, CheckType, ElementData, NodeData, NodeDef, NodeFlags, ProviderData, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, asElementData, asQueryList, asTextData} from './types';
|
||||
import {NOOP, checkBindingNoChanges, isComponentView, markParentViewsForCheckProjectedViews, resolveViewDefinition} from './util';
|
||||
import {NOOP, checkBindingNoChanges, isComponentView, markParentViewsForCheckProjectedViews, resolveDefinition, tokenKey} from './util';
|
||||
import {detachProjectedView} from './view_attach';
|
||||
|
||||
export function viewDef(
|
||||
@ -102,7 +102,7 @@ export function viewDef(
|
||||
const isPrivateService = (node.flags & NodeFlags.PrivateProvider) !== 0;
|
||||
const isComponent = (node.flags & NodeFlags.Component) !== 0;
|
||||
if (!isPrivateService || isComponent) {
|
||||
currentParent !.element !.publicProviders ![node.provider !.tokenKey] = node;
|
||||
currentParent !.element !.publicProviders ![tokenKey(node.provider !.token)] = node;
|
||||
} else {
|
||||
if (!currentElementHasPrivateProviders) {
|
||||
currentElementHasPrivateProviders = true;
|
||||
@ -110,7 +110,7 @@ export function viewDef(
|
||||
currentParent !.element !.allProviders =
|
||||
Object.create(currentParent !.element !.publicProviders);
|
||||
}
|
||||
currentParent !.element !.allProviders ![node.provider !.tokenKey] = node;
|
||||
currentParent !.element !.allProviders ![tokenKey(node.provider !.token)] = node;
|
||||
}
|
||||
if (isComponent) {
|
||||
currentParent !.element !.componentProvider = node;
|
||||
@ -240,7 +240,7 @@ function createViewNodes(view: ViewData) {
|
||||
const el = createElement(view, renderHost, nodeDef) as any;
|
||||
let componentView: ViewData = undefined !;
|
||||
if (nodeDef.flags & NodeFlags.ComponentView) {
|
||||
const compViewDef = resolveViewDefinition(nodeDef.element !.componentView !);
|
||||
const compViewDef = resolveDefinition(nodeDef.element !.componentView !);
|
||||
const rendererType = nodeDef.element !.componentRendererType;
|
||||
let compRenderer: Renderer2;
|
||||
if (!rendererType) {
|
||||
|
Reference in New Issue
Block a user