refactor(ivy): special injection tokens should not be cached (#26048)
PR Close #26048
This commit is contained in:
parent
64aa6701f6
commit
d5f47d6b71
|
@ -14,7 +14,7 @@ import {Sanitizer} from '../sanitization/security';
|
||||||
|
|
||||||
import {assertComponentType, assertDefined} from './assert';
|
import {assertComponentType, assertDefined} from './assert';
|
||||||
import {queueInitHooks, queueLifecycleHooks} from './hooks';
|
import {queueInitHooks, queueLifecycleHooks} from './hooks';
|
||||||
import {CLEAN_PROMISE, baseDirectiveCreate, createLViewData, createTView, detectChangesInternal, enterView, executeInitAndContentHooks, getRootView, hostElement, initChangeDetectorIfExisting, leaveView, locateHostElement, setHostBindings, queueHostBindingForCheck,} from './instructions';
|
import {CLEAN_PROMISE, baseDirectiveCreate, createLViewData, createTView, detectChangesInternal, enterView, executeInitAndContentHooks, getRootView, hostElement, leaveView, locateHostElement, setHostBindings, queueHostBindingForCheck,} from './instructions';
|
||||||
import {ComponentDef, ComponentDefInternal, ComponentType} from './interfaces/definition';
|
import {ComponentDef, ComponentDefInternal, ComponentType} from './interfaces/definition';
|
||||||
import {LElementNode} from './interfaces/node';
|
import {LElementNode} from './interfaces/node';
|
||||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||||
|
@ -150,7 +150,6 @@ export function createRootComponent<T>(
|
||||||
if (componentDef.hostBindings) queueHostBindingForCheck(0, componentDef.hostVars);
|
if (componentDef.hostBindings) queueHostBindingForCheck(0, componentDef.hostVars);
|
||||||
rootContext.components.push(component);
|
rootContext.components.push(component);
|
||||||
(elementNode.data as LViewData)[CONTEXT] = component;
|
(elementNode.data as LViewData)[CONTEXT] = component;
|
||||||
initChangeDetectorIfExisting(elementNode.nodeInjector, component, elementNode.data as LViewData);
|
|
||||||
|
|
||||||
hostFeatures && hostFeatures.forEach((feature) => feature(component, componentDef));
|
hostFeatures && hostFeatures.forEach((feature) => feature(component, componentDef));
|
||||||
setHostBindings(rootView[TVIEW].hostBindings);
|
setHostBindings(rootView[TVIEW].hostBindings);
|
||||||
|
|
|
@ -145,10 +145,6 @@ export function getOrCreateNodeInjectorForNode(
|
||||||
cbf5: parentInjector == null ? 0 : parentInjector.cbf5 | parentInjector.bf5,
|
cbf5: parentInjector == null ? 0 : parentInjector.cbf5 | parentInjector.bf5,
|
||||||
cbf6: parentInjector == null ? 0 : parentInjector.cbf6 | parentInjector.bf6,
|
cbf6: parentInjector == null ? 0 : parentInjector.cbf6 | parentInjector.bf6,
|
||||||
cbf7: parentInjector == null ? 0 : parentInjector.cbf7 | parentInjector.bf7,
|
cbf7: parentInjector == null ? 0 : parentInjector.cbf7 | parentInjector.bf7,
|
||||||
templateRef: null,
|
|
||||||
viewContainerRef: null,
|
|
||||||
elementRef: null,
|
|
||||||
changeDetectorRef: null,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +203,7 @@ export function directiveInject<T>(
|
||||||
* @returns The ElementRef instance to use
|
* @returns The ElementRef instance to use
|
||||||
*/
|
*/
|
||||||
export function injectElementRef(): viewEngine_ElementRef {
|
export function injectElementRef(): viewEngine_ElementRef {
|
||||||
return getOrCreateElementRef(getOrCreateNodeInjector());
|
return createElementRef(getPreviousOrParentTNode(), _getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,7 +213,7 @@ export function injectElementRef(): viewEngine_ElementRef {
|
||||||
* @returns The TemplateRef instance to use
|
* @returns The TemplateRef instance to use
|
||||||
*/
|
*/
|
||||||
export function injectTemplateRef<T>(): viewEngine_TemplateRef<T> {
|
export function injectTemplateRef<T>(): viewEngine_TemplateRef<T> {
|
||||||
return getOrCreateTemplateRef<T>(getOrCreateNodeInjector());
|
return createTemplateRef<T>(getPreviousOrParentTNode(), _getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -227,12 +223,14 @@ export function injectTemplateRef<T>(): viewEngine_TemplateRef<T> {
|
||||||
* @returns The ViewContainerRef instance to use
|
* @returns The ViewContainerRef instance to use
|
||||||
*/
|
*/
|
||||||
export function injectViewContainerRef(): viewEngine_ViewContainerRef {
|
export function injectViewContainerRef(): viewEngine_ViewContainerRef {
|
||||||
return getOrCreateContainerRef(getOrCreateNodeInjector());
|
const previousTNode =
|
||||||
|
getPreviousOrParentTNode() as TElementNode | TElementContainerNode | TContainerNode;
|
||||||
|
return createContainerRef(previousTNode, _getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
|
/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
|
||||||
export function injectChangeDetectorRef(): viewEngine_ChangeDetectorRef {
|
export function injectChangeDetectorRef(): viewEngine_ChangeDetectorRef {
|
||||||
return getOrCreateChangeDetectorRef(getOrCreateNodeInjector(), null);
|
return createViewRef(getPreviousOrParentTNode(), _getViewData(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -302,34 +300,25 @@ export function injectAttribute(attrNameToInject: string): string|undefined {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
|
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
|
||||||
* Or, if it already exists, retrieves the existing instance.
|
|
||||||
*
|
*
|
||||||
|
* @param hostTNode The node that is requesting a ChangeDetectorRef
|
||||||
|
* @param hostView The view to which the node belongs
|
||||||
|
* @param context The context for this change detector ref
|
||||||
* @returns The ChangeDetectorRef to use
|
* @returns The ChangeDetectorRef to use
|
||||||
*/
|
*/
|
||||||
export function getOrCreateChangeDetectorRef(
|
export function createViewRef(
|
||||||
di: LInjector, context: any): viewEngine_ChangeDetectorRef {
|
hostTNode: TNode, hostView: LViewData, context: any): viewEngine_ChangeDetectorRef {
|
||||||
if (di.changeDetectorRef) return di.changeDetectorRef;
|
if (isComponent(hostTNode)) {
|
||||||
|
const componentIndex = hostTNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||||
const currentTNode = di.tNode;
|
const componentView = getLNode(hostTNode, hostView).data as LViewData;
|
||||||
if (isComponent(currentTNode)) {
|
return new ViewRef(componentView, context, componentIndex);
|
||||||
return di.changeDetectorRef =
|
} else if (hostTNode.type === TNodeType.Element) {
|
||||||
new ViewRef(getLNode(currentTNode, di.view).data as LViewData, context);
|
const hostComponentView = findComponentView(hostView);
|
||||||
} else if (currentTNode.type === TNodeType.Element) {
|
return new ViewRef(hostComponentView, hostComponentView[CONTEXT], -1);
|
||||||
return di.changeDetectorRef = getOrCreateHostChangeDetector(di.view);
|
|
||||||
}
|
}
|
||||||
return null !;
|
return null !;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets or creates ChangeDetectorRef for the closest host component */
|
|
||||||
function getOrCreateHostChangeDetector(currentView: LViewData): viewEngine_ChangeDetectorRef {
|
|
||||||
const hostComponentView = findComponentView(currentView);
|
|
||||||
const hostNode = getHostElementNode(hostComponentView) !;
|
|
||||||
const hostInjector = hostNode.nodeInjector;
|
|
||||||
const existingRef = hostInjector && hostInjector.changeDetectorRef;
|
|
||||||
|
|
||||||
return existingRef ? existingRef : new ViewRef(hostComponentView, hostComponentView[CONTEXT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOrCreateRenderer2(di: LInjector): Renderer2 {
|
function getOrCreateRenderer2(di: LInjector): Renderer2 {
|
||||||
const renderer = di.view[RENDERER];
|
const renderer = di.view[RENDERER];
|
||||||
if (isProceduralRenderer(renderer)) {
|
if (isProceduralRenderer(renderer)) {
|
||||||
|
@ -537,44 +526,44 @@ function sameHostView(injector: LInjector): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ReadFromInjectorFn<T> {
|
export class ReadFromInjectorFn<T> {
|
||||||
constructor(readonly read: (injector: LInjector, tNode: TNode, directiveIndex?: number) => T) {}
|
constructor(readonly read: (tNode: TNode, view: LViewData, directiveIndex?: number) => T) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an ElementRef for a given node injector and stores it on the injector.
|
* Creates an ElementRef for a given node injector and stores it on the injector.
|
||||||
* Or, if the ElementRef already exists, retrieves the existing ElementRef.
|
|
||||||
*
|
*
|
||||||
* @param di The node injector where we should store a created ElementRef
|
* @param di The node injector where we should store a created ElementRef
|
||||||
* @returns The ElementRef instance to use
|
* @returns The ElementRef instance to use
|
||||||
*/
|
*/
|
||||||
export function getOrCreateElementRef(di: LInjector): viewEngine_ElementRef {
|
export function createElementRef(tNode: TNode, view: LViewData): viewEngine_ElementRef {
|
||||||
return di.elementRef || (di.elementRef = new ElementRef(getLNode(di.tNode, di.view).native));
|
return new ElementRef(getLNode(tNode, view).native);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const QUERY_READ_TEMPLATE_REF = <QueryReadType<viewEngine_TemplateRef<any>>>(
|
export const QUERY_READ_TEMPLATE_REF = <QueryReadType<viewEngine_TemplateRef<any>>>(
|
||||||
new ReadFromInjectorFn<viewEngine_TemplateRef<any>>(
|
new ReadFromInjectorFn<viewEngine_TemplateRef<any>>(
|
||||||
(injector: LInjector) => getOrCreateTemplateRef(injector)) as any);
|
(tNode: TNode, view: LViewData) => { return createTemplateRef(tNode, view);}) as any);
|
||||||
|
|
||||||
export const QUERY_READ_CONTAINER_REF = <QueryReadType<viewEngine_ViewContainerRef>>(
|
export const QUERY_READ_CONTAINER_REF = <QueryReadType<viewEngine_ViewContainerRef>>(
|
||||||
new ReadFromInjectorFn<viewEngine_ViewContainerRef>(
|
new ReadFromInjectorFn<viewEngine_ViewContainerRef>(
|
||||||
(injector: LInjector) => getOrCreateContainerRef(injector)) as any);
|
(tNode: TNode, view: LViewData) => createContainerRef(
|
||||||
|
tNode as TElementNode | TContainerNode | TElementContainerNode, view)) as any);
|
||||||
|
|
||||||
export const QUERY_READ_ELEMENT_REF =
|
export const QUERY_READ_ELEMENT_REF =
|
||||||
<QueryReadType<viewEngine_ElementRef>>(new ReadFromInjectorFn<viewEngine_ElementRef>(
|
<QueryReadType<viewEngine_ElementRef>>(new ReadFromInjectorFn<viewEngine_ElementRef>(
|
||||||
(injector: LInjector) => getOrCreateElementRef(injector)) as any);
|
(tNode: TNode, view: LViewData) => createElementRef(tNode, view)) as any);
|
||||||
|
|
||||||
export const QUERY_READ_FROM_NODE =
|
export const QUERY_READ_FROM_NODE =
|
||||||
(new ReadFromInjectorFn<any>((injector: LInjector, tNode: TNode, directiveIdx: number) => {
|
(new ReadFromInjectorFn<any>((tNode: TNode, view: LViewData, directiveIdx: number) => {
|
||||||
ngDevMode && assertNodeOfPossibleTypes(
|
ngDevMode && assertNodeOfPossibleTypes(
|
||||||
tNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
tNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||||
if (directiveIdx > -1) {
|
if (directiveIdx > -1) {
|
||||||
return injector.view[DIRECTIVES] ![directiveIdx];
|
return view[DIRECTIVES] ![directiveIdx];
|
||||||
}
|
}
|
||||||
if (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) {
|
if (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) {
|
||||||
return getOrCreateElementRef(injector);
|
return createElementRef(tNode, view);
|
||||||
}
|
}
|
||||||
if (tNode.type === TNodeType.Container) {
|
if (tNode.type === TNodeType.Container) {
|
||||||
return getOrCreateTemplateRef(injector);
|
return createTemplateRef(tNode, view);
|
||||||
}
|
}
|
||||||
if (ngDevMode) {
|
if (ngDevMode) {
|
||||||
// should never happen
|
// should never happen
|
||||||
|
@ -586,42 +575,38 @@ export const QUERY_READ_FROM_NODE =
|
||||||
class ElementRef extends viewEngine_ElementRef {}
|
class ElementRef extends viewEngine_ElementRef {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
|
* Creates a ViewContainerRef and stores it on the injector.
|
||||||
* already exists, retrieves the existing ViewContainerRef.
|
|
||||||
*
|
*
|
||||||
|
* @param hostTNode The node that is requesting a ViewContainerRef
|
||||||
|
* @param hostView The view to which the node belongs
|
||||||
* @returns The ViewContainerRef instance to use
|
* @returns The ViewContainerRef instance to use
|
||||||
*/
|
*/
|
||||||
export function getOrCreateContainerRef(di: LInjector): viewEngine_ViewContainerRef {
|
export function createContainerRef(
|
||||||
if (!di.viewContainerRef) {
|
hostTNode: TElementNode | TContainerNode | TElementContainerNode,
|
||||||
const hostLNode =
|
hostView: LViewData): viewEngine_ViewContainerRef {
|
||||||
getPreviousOrParentNode() as LElementNode | LContainerNode | LElementContainerNode;
|
const hostLNode = getLNode(hostTNode, hostView);
|
||||||
const hostTNode = getPreviousOrParentTNode() as TElementNode | TContainerNode;
|
ngDevMode && assertNodeOfPossibleTypes(
|
||||||
ngDevMode && assertNodeOfPossibleTypes(
|
hostTNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||||
hostTNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
|
||||||
|
|
||||||
const hostView = di.view;
|
const lContainer = createLContainer(hostView, true);
|
||||||
const lContainer = createLContainer(hostView, true);
|
const comment = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
|
||||||
const comment = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
|
const lContainerNode: LContainerNode =
|
||||||
const lContainerNode: LContainerNode =
|
createLNodeObject(TNodeType.Container, hostLNode.nodeInjector, comment, lContainer);
|
||||||
createLNodeObject(TNodeType.Container, hostLNode.nodeInjector, comment, lContainer);
|
|
||||||
|
|
||||||
lContainer[RENDER_PARENT] = getRenderParent(hostTNode, hostView);
|
lContainer[RENDER_PARENT] = getRenderParent(hostTNode, hostView);
|
||||||
|
|
||||||
appendChild(comment, hostTNode, hostView);
|
appendChild(comment, hostTNode, hostView);
|
||||||
|
|
||||||
if (!hostTNode.dynamicContainerNode) {
|
if (!hostTNode.dynamicContainerNode) {
|
||||||
hostTNode.dynamicContainerNode =
|
hostTNode.dynamicContainerNode =
|
||||||
createTNode(TNodeType.Container, -1, null, null, hostTNode, null);
|
createTNode(TNodeType.Container, -1, null, null, hostTNode, null);
|
||||||
}
|
|
||||||
|
|
||||||
hostLNode.dynamicLContainerNode = lContainerNode;
|
|
||||||
addToViewTree(hostView, hostTNode.index as number, lContainer);
|
|
||||||
|
|
||||||
di.viewContainerRef = new ViewContainerRef(
|
|
||||||
lContainer, hostTNode.dynamicContainerNode as TContainerNode, hostTNode, hostView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return di.viewContainerRef;
|
hostLNode.dynamicLContainerNode = lContainerNode;
|
||||||
|
addToViewTree(hostView, hostTNode.index as number, lContainer);
|
||||||
|
|
||||||
|
return new ViewContainerRef(
|
||||||
|
lContainer, hostTNode.dynamicContainerNode as TContainerNode, hostTNode, hostView);
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NodeInjector implements Injector {
|
export class NodeInjector implements Injector {
|
||||||
|
@ -629,16 +614,16 @@ export class NodeInjector implements Injector {
|
||||||
|
|
||||||
get(token: any): any {
|
get(token: any): any {
|
||||||
if (token === viewEngine_TemplateRef) {
|
if (token === viewEngine_TemplateRef) {
|
||||||
return getOrCreateTemplateRef(this._lInjector);
|
return createTemplateRef(this._lInjector.tNode, this._lInjector.view);
|
||||||
}
|
}
|
||||||
if (token === viewEngine_ViewContainerRef) {
|
if (token === viewEngine_ViewContainerRef) {
|
||||||
return getOrCreateContainerRef(this._lInjector);
|
return createContainerRef(this._lInjector.tNode, this._lInjector.view);
|
||||||
}
|
}
|
||||||
if (token === viewEngine_ElementRef) {
|
if (token === viewEngine_ElementRef) {
|
||||||
return getOrCreateElementRef(this._lInjector);
|
return createElementRef(this._lInjector.tNode, this._lInjector.view);
|
||||||
}
|
}
|
||||||
if (token === viewEngine_ChangeDetectorRef) {
|
if (token === viewEngine_ChangeDetectorRef) {
|
||||||
return getOrCreateChangeDetectorRef(this._lInjector, null);
|
return createViewRef(this._lInjector.tNode, this._lInjector.view, null);
|
||||||
}
|
}
|
||||||
if (token === Renderer2) {
|
if (token === Renderer2) {
|
||||||
return getOrCreateRenderer2(this._lInjector);
|
return getOrCreateRenderer2(this._lInjector);
|
||||||
|
@ -666,7 +651,7 @@ class ViewContainerRef extends viewEngine_ViewContainerRef {
|
||||||
// TODO: Remove LNode lookup when removing LNode.nodeInjector
|
// TODO: Remove LNode lookup when removing LNode.nodeInjector
|
||||||
const injector =
|
const injector =
|
||||||
getOrCreateNodeInjectorForNode(this._getHostNode(), this._hostTNode, this._hostView);
|
getOrCreateNodeInjectorForNode(this._getHostNode(), this._hostTNode, this._hostView);
|
||||||
return getOrCreateElementRef(injector);
|
return createElementRef(injector.tNode, injector.view);
|
||||||
}
|
}
|
||||||
|
|
||||||
get injector(): Injector {
|
get injector(): Injector {
|
||||||
|
@ -776,23 +761,20 @@ class ViewContainerRef extends viewEngine_ViewContainerRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a TemplateRef and stores it on the injector. Or, if the TemplateRef already
|
* Creates a TemplateRef and stores it on the injector.
|
||||||
* exists, retrieves the existing TemplateRef.
|
|
||||||
*
|
*
|
||||||
* @param di The node injector where we should store a created TemplateRef
|
* @param hostTNode The node that is requesting a TemplateRef
|
||||||
|
* @param hostView The view to which the node belongs
|
||||||
* @returns The TemplateRef instance to use
|
* @returns The TemplateRef instance to use
|
||||||
*/
|
*/
|
||||||
export function getOrCreateTemplateRef<T>(di: LInjector): viewEngine_TemplateRef<T> {
|
export function createTemplateRef<T>(
|
||||||
if (!di.templateRef) {
|
hostTNode: TNode, hostView: LViewData): viewEngine_TemplateRef<T> {
|
||||||
const hostNode = getPreviousOrParentNode() as LContainerNode;
|
const hostNode = getLNode(hostTNode, hostView);
|
||||||
const hostTNode = getPreviousOrParentTNode() as TContainerNode;
|
ngDevMode && assertNodeType(hostTNode, TNodeType.Container);
|
||||||
ngDevMode && assertNodeType(hostTNode, TNodeType.Container);
|
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
|
||||||
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
|
return new TemplateRef<any>(
|
||||||
di.templateRef = new TemplateRef<any>(
|
hostView, createElementRef(hostTNode, hostView), hostTNode.tViews as TView, getRenderer(),
|
||||||
di.view, getOrCreateElementRef(di), hostTNode.tViews as TView, getRenderer(),
|
hostNode.data ![QUERIES]);
|
||||||
hostNode.data ![QUERIES]);
|
|
||||||
}
|
|
||||||
return di.templateRef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFactoryOf<T>(type: Type<any>): ((type?: Type<T>) => T)|null {
|
export function getFactoryOf<T>(type: Type<any>): ((type?: Type<T>) => T)|null {
|
||||||
|
@ -835,7 +817,7 @@ class TemplateRef<T> extends viewEngine_TemplateRef<T> {
|
||||||
insertView(lView, container, hostView !, index !, tContainerNode !.parent !.index);
|
insertView(lView, container, hostView !, index !, tContainerNode !.parent !.index);
|
||||||
}
|
}
|
||||||
renderEmbeddedTemplate(lView, this._tView, context, RenderFlags.Create);
|
renderEmbeddedTemplate(lView, this._tView, context, RenderFlags.Create);
|
||||||
const viewRef = new ViewRef(lView, context);
|
const viewRef = new ViewRef(lView, context, -1);
|
||||||
viewRef._tViewNode = lView[HOST_NODE] as TViewNode;
|
viewRef._tViewNode = lView[HOST_NODE] as TViewNode;
|
||||||
return viewRef;
|
return viewRef;
|
||||||
}
|
}
|
||||||
|
@ -846,7 +828,5 @@ class TemplateRef<T> extends viewEngine_TemplateRef<T> {
|
||||||
* `<ng-template>` element.
|
* `<ng-template>` element.
|
||||||
*/
|
*/
|
||||||
export function templateRefExtractor(tNode: TContainerNode, currentView: LViewData) {
|
export function templateRefExtractor(tNode: TContainerNode, currentView: LViewData) {
|
||||||
// TODO: remove this lookup with removing LNode.nodeInjector
|
return createTemplateRef(tNode, currentView);
|
||||||
const lNode = getLNode(tNode, currentView) as LContainerNode;
|
|
||||||
return getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(lNode, tNode, currentView));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -899,12 +899,18 @@ function findDirectiveMatches(tNode: TNode): CurrentMatchesList|null {
|
||||||
for (let i = 0; i < registry.length; i++) {
|
for (let i = 0; i < registry.length; i++) {
|
||||||
const def = registry[i];
|
const def = registry[i];
|
||||||
if (isNodeMatchingSelectorList(tNode, def.selectors !)) {
|
if (isNodeMatchingSelectorList(tNode, def.selectors !)) {
|
||||||
|
matches || (matches = []);
|
||||||
if ((def as ComponentDefInternal<any>).template) {
|
if ((def as ComponentDefInternal<any>).template) {
|
||||||
if (tNode.flags & TNodeFlags.isComponent) throwMultipleComponentError(tNode);
|
if (tNode.flags & TNodeFlags.isComponent) throwMultipleComponentError(tNode);
|
||||||
|
addComponentLogic(def as ComponentDefInternal<any>);
|
||||||
tNode.flags = TNodeFlags.isComponent;
|
tNode.flags = TNodeFlags.isComponent;
|
||||||
|
|
||||||
|
// The component is always stored first with directives after.
|
||||||
|
matches.unshift(def, null);
|
||||||
|
} else {
|
||||||
|
matches.push(def, null);
|
||||||
}
|
}
|
||||||
if (def.diPublic) def.diPublic(def);
|
if (def.diPublic) def.diPublic(def);
|
||||||
(matches || (matches = [])).push(def, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -948,14 +954,6 @@ export function queueHostBindingForCheck(dirIndex: number, hostVars: number): vo
|
||||||
])).push(dirIndex, previousOrParentTNode.index - HEADER_OFFSET);
|
])).push(dirIndex, previousOrParentTNode.index - HEADER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the context for a ChangeDetectorRef to the given instance. */
|
|
||||||
export function initChangeDetectorIfExisting(
|
|
||||||
injector: LInjector | null, instance: any, view: LViewData): void {
|
|
||||||
if (injector && injector.changeDetectorRef != null) {
|
|
||||||
(injector.changeDetectorRef as ViewRef<any>)._setComponentContext(view, instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function instantiates the given directives.
|
* This function instantiates the given directives.
|
||||||
*/
|
*/
|
||||||
|
@ -976,6 +974,12 @@ function instantiateDirectivesDirectly() {
|
||||||
|
|
||||||
for (let i = start; i < end; i++) {
|
for (let i = start; i < end; i++) {
|
||||||
const def: DirectiveDefInternal<any> = tDirectives[i];
|
const def: DirectiveDefInternal<any> = tDirectives[i];
|
||||||
|
|
||||||
|
// Component view must be set on node before the factory is created so
|
||||||
|
// ChangeDetectorRefs have a way to store component view on creation.
|
||||||
|
if ((def as ComponentDefInternal<any>).template) {
|
||||||
|
addComponentLogic(def as ComponentDefInternal<any>);
|
||||||
|
}
|
||||||
directiveCreate(i, def.factory(), def);
|
directiveCreate(i, def.factory(), def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1698,13 +1702,11 @@ export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
|
||||||
export function directiveCreate<T>(
|
export function directiveCreate<T>(
|
||||||
directiveDefIdx: number, directive: T,
|
directiveDefIdx: number, directive: T,
|
||||||
directiveDef: DirectiveDefInternal<T>| ComponentDefInternal<T>): T {
|
directiveDef: DirectiveDefInternal<T>| ComponentDefInternal<T>): T {
|
||||||
const hostNode = getPreviousOrParentNode() !;
|
const hostNode = getLNode(previousOrParentTNode, viewData);
|
||||||
const instance = baseDirectiveCreate(directiveDefIdx, directive, directiveDef, hostNode);
|
const instance = baseDirectiveCreate(directiveDefIdx, directive, directiveDef, hostNode);
|
||||||
|
|
||||||
const isComponent = (directiveDef as ComponentDefInternal<T>).template;
|
if ((directiveDef as ComponentDefInternal<T>).template) {
|
||||||
if (isComponent) {
|
hostNode.data ![CONTEXT] = directive;
|
||||||
addComponentLogic(
|
|
||||||
directiveDefIdx, directive, directiveDef as ComponentDefInternal<T>, hostNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstTemplatePass) {
|
if (firstTemplatePass) {
|
||||||
|
@ -1727,8 +1729,9 @@ export function directiveCreate<T>(
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addComponentLogic<T>(
|
function addComponentLogic<T>(def: ComponentDefInternal<T>): void {
|
||||||
directiveIndex: number, instance: T, def: ComponentDefInternal<T>, hostNode: LNode): void {
|
const hostNode = getLNode(previousOrParentTNode, viewData);
|
||||||
|
|
||||||
const tView = getOrCreateTView(
|
const tView = getOrCreateTView(
|
||||||
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery);
|
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery);
|
||||||
|
|
||||||
|
@ -1737,15 +1740,13 @@ function addComponentLogic<T>(
|
||||||
const componentView = addToViewTree(
|
const componentView = addToViewTree(
|
||||||
viewData, previousOrParentTNode.index as number,
|
viewData, previousOrParentTNode.index as number,
|
||||||
createLViewData(
|
createLViewData(
|
||||||
rendererFactory.createRenderer(hostNode.native as RElement, def), tView, instance,
|
rendererFactory.createRenderer(hostNode.native as RElement, def), tView, null,
|
||||||
def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, getCurrentSanitizer()));
|
def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, getCurrentSanitizer()));
|
||||||
|
|
||||||
// We need to set the host node/data here because when the component LNode was created,
|
// We need to set the host node/data here because when the component LNode was created,
|
||||||
// we didn't yet know it was a component (just an element).
|
// we didn't yet know it was a component (just an element).
|
||||||
(hostNode as{data: LViewData}).data = componentView;
|
(hostNode as{data: LViewData}).data = componentView;
|
||||||
(componentView as LViewData)[HOST_NODE] = getPreviousOrParentTNode() as TElementNode;
|
(componentView as LViewData)[HOST_NODE] = previousOrParentTNode as TElementNode;
|
||||||
|
|
||||||
initChangeDetectorIfExisting(hostNode.nodeInjector, instance, componentView);
|
|
||||||
|
|
||||||
if (firstTemplatePass) queueComponentIndexForCheck();
|
if (firstTemplatePass) queueComponentIndexForCheck();
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,22 +70,6 @@ export interface LInjector {
|
||||||
cbf5: number;
|
cbf5: number;
|
||||||
cbf6: number;
|
cbf6: number;
|
||||||
cbf7: number;
|
cbf7: number;
|
||||||
|
|
||||||
/** Stores the TemplateRef so subsequent injections of the TemplateRef get the same instance. */
|
|
||||||
templateRef: TemplateRef<any>|null;
|
|
||||||
|
|
||||||
/** Stores the ViewContainerRef so subsequent injections of the ViewContainerRef get the same
|
|
||||||
* instance. */
|
|
||||||
viewContainerRef: ViewContainerRef|null;
|
|
||||||
|
|
||||||
/** Stores the ElementRef so subsequent injections of the ElementRef get the same instance. */
|
|
||||||
elementRef: ElementRef|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the ChangeDetectorRef so subsequent injections of the ChangeDetectorRef get the
|
|
||||||
* same instance.
|
|
||||||
*/
|
|
||||||
changeDetectorRef: ChangeDetectorRef|null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||||
|
|
|
@ -265,10 +265,10 @@ function getIdxOfMatchingDirective(tNode: TNode, currentView: LViewData, type: T
|
||||||
}
|
}
|
||||||
|
|
||||||
function readFromNodeInjector(
|
function readFromNodeInjector(
|
||||||
nodeInjector: LInjector, tNode: TNode, currentView: LViewData,
|
tNode: TNode, currentView: LViewData, read: QueryReadType<any>| Type<any>,
|
||||||
read: QueryReadType<any>| Type<any>, directiveIdx: number): any {
|
directiveIdx: number): any {
|
||||||
if (read instanceof ReadFromInjectorFn) {
|
if (read instanceof ReadFromInjectorFn) {
|
||||||
return read.read(nodeInjector, tNode, directiveIdx);
|
return read.read(tNode, currentView, directiveIdx);
|
||||||
} else {
|
} else {
|
||||||
const matchingIdx = getIdxOfMatchingDirective(tNode, currentView, read as Type<any>);
|
const matchingIdx = getIdxOfMatchingDirective(tNode, currentView, read as Type<any>);
|
||||||
if (matchingIdx !== null) {
|
if (matchingIdx !== null) {
|
||||||
|
@ -282,10 +282,6 @@ function add(
|
||||||
query: LQuery<any>| null, tNode: TElementNode | TContainerNode | TElementContainerNode) {
|
query: LQuery<any>| null, tNode: TElementNode | TContainerNode | TElementContainerNode) {
|
||||||
const currentView = _getViewData();
|
const currentView = _getViewData();
|
||||||
|
|
||||||
// TODO: remove this lookup when nodeInjector is removed from LNode
|
|
||||||
const nodeInjector =
|
|
||||||
getOrCreateNodeInjectorForNode(getLNode(tNode, currentView), tNode, currentView);
|
|
||||||
|
|
||||||
while (query) {
|
while (query) {
|
||||||
const predicate = query.predicate;
|
const predicate = query.predicate;
|
||||||
const type = predicate.type;
|
const type = predicate.type;
|
||||||
|
@ -294,8 +290,8 @@ function add(
|
||||||
if (directiveIdx !== null) {
|
if (directiveIdx !== null) {
|
||||||
// a node is matching a predicate - determine what to read
|
// a node is matching a predicate - determine what to read
|
||||||
// if read token and / or strategy is not specified, use type as read token
|
// if read token and / or strategy is not specified, use type as read token
|
||||||
const result = readFromNodeInjector(
|
const result =
|
||||||
nodeInjector, tNode, currentView, predicate.read || type, directiveIdx);
|
readFromNodeInjector(tNode, currentView, predicate.read || type, directiveIdx);
|
||||||
if (result !== null) {
|
if (result !== null) {
|
||||||
addMatch(query, result);
|
addMatch(query, result);
|
||||||
}
|
}
|
||||||
|
@ -308,8 +304,7 @@ function add(
|
||||||
// a node is matching a predicate - determine what to read
|
// a node is matching a predicate - determine what to read
|
||||||
// note that queries using name selector must specify read strategy
|
// note that queries using name selector must specify read strategy
|
||||||
ngDevMode && assertDefined(predicate.read, 'the node should have a predicate');
|
ngDevMode && assertDefined(predicate.read, 'the node should have a predicate');
|
||||||
const result = readFromNodeInjector(
|
const result = readFromNodeInjector(tNode, currentView, predicate.read !, directiveIdx);
|
||||||
nodeInjector, tNode, currentView, predicate.read !, directiveIdx);
|
|
||||||
if (result !== null) {
|
if (result !== null) {
|
||||||
addMatch(query, result);
|
addMatch(query, result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, InternalViewRef as viewEn
|
||||||
|
|
||||||
import {checkNoChanges, checkNoChangesInRootView, detectChanges, detectChangesInRootView, getRendererFactory, markViewDirty, storeCleanupFn, viewAttached} from './instructions';
|
import {checkNoChanges, checkNoChangesInRootView, detectChanges, detectChangesInRootView, getRendererFactory, markViewDirty, storeCleanupFn, viewAttached} from './instructions';
|
||||||
import {TViewNode} from './interfaces/node';
|
import {TViewNode} from './interfaces/node';
|
||||||
import {FLAGS, LViewData, LViewFlags} from './interfaces/view';
|
import {DIRECTIVES, FLAGS, LViewData, LViewFlags, PARENT} from './interfaces/view';
|
||||||
import {destroyLView} from './node_manipulation';
|
import {destroyLView} from './node_manipulation';
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,20 +37,14 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
|
||||||
*/
|
*/
|
||||||
_tViewNode: TViewNode|null = null;
|
_tViewNode: TViewNode|null = null;
|
||||||
|
|
||||||
context: T;
|
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
rootNodes !: any[];
|
rootNodes !: any[];
|
||||||
|
|
||||||
constructor(_view: LViewData, context: T|null) {
|
constructor(_view: LViewData, private _context: T|null, private _componentIndex: number) {
|
||||||
this.context = context !;
|
|
||||||
this._view = _view;
|
this._view = _view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
get context(): T { return this._context ? this._context : this._lookUpContext(); }
|
||||||
_setComponentContext(view: LViewData, context: T) {
|
|
||||||
this._view = view;
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
get destroyed(): boolean {
|
get destroyed(): boolean {
|
||||||
return (this._view[FLAGS] & LViewFlags.Destroyed) === LViewFlags.Destroyed;
|
return (this._view[FLAGS] & LViewFlags.Destroyed) === LViewFlags.Destroyed;
|
||||||
|
@ -260,11 +254,15 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
|
||||||
detachFromAppRef() { this._appRef = null; }
|
detachFromAppRef() { this._appRef = null; }
|
||||||
|
|
||||||
attachToAppRef(appRef: ApplicationRef) { this._appRef = appRef; }
|
attachToAppRef(appRef: ApplicationRef) { this._appRef = appRef; }
|
||||||
|
|
||||||
|
private _lookUpContext(): T {
|
||||||
|
return this._context = this._view[PARENT] ![DIRECTIVES] ![this._componentIndex] as T;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export class RootViewRef<T> extends ViewRef<T> {
|
export class RootViewRef<T> extends ViewRef<T> {
|
||||||
constructor(public _view: LViewData) { super(_view, null); }
|
constructor(public _view: LViewData) { super(_view, null, -1); }
|
||||||
|
|
||||||
detectChanges(): void { detectChangesInRootView(this._view); }
|
detectChanges(): void { detectChangesInRootView(this._view); }
|
||||||
|
|
||||||
|
|
|
@ -266,9 +266,6 @@
|
||||||
{
|
{
|
||||||
"name": "hostElement"
|
"name": "hostElement"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "initChangeDetectorIfExisting"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "invertObject"
|
"name": "invertObject"
|
||||||
},
|
},
|
||||||
|
|
|
@ -404,9 +404,15 @@
|
||||||
{
|
{
|
||||||
"name": "contextViewData"
|
"name": "contextViewData"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createContainerRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createDirectivesAndLocals"
|
"name": "createDirectivesAndLocals"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createElementRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createEmbeddedViewAndNode"
|
"name": "createEmbeddedViewAndNode"
|
||||||
},
|
},
|
||||||
|
@ -443,6 +449,9 @@
|
||||||
{
|
{
|
||||||
"name": "createTView"
|
"name": "createTView"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createTemplateRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createTextNode"
|
"name": "createTextNode"
|
||||||
},
|
},
|
||||||
|
@ -452,6 +461,9 @@
|
||||||
{
|
{
|
||||||
"name": "createViewQuery"
|
"name": "createViewQuery"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createViewRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "defineComponent"
|
"name": "defineComponent"
|
||||||
},
|
},
|
||||||
|
@ -620,18 +632,6 @@
|
||||||
{
|
{
|
||||||
"name": "getMultiStartIndex"
|
"name": "getMultiStartIndex"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "getOrCreateChangeDetectorRef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getOrCreateContainerRef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getOrCreateElementRef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getOrCreateHostChangeDetector"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "getOrCreateInjectable"
|
"name": "getOrCreateInjectable"
|
||||||
},
|
},
|
||||||
|
@ -647,9 +647,6 @@
|
||||||
{
|
{
|
||||||
"name": "getOrCreateTView"
|
"name": "getOrCreateTView"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "getOrCreateTemplateRef"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "getParentLNode"
|
"name": "getParentLNode"
|
||||||
},
|
},
|
||||||
|
@ -719,9 +716,6 @@
|
||||||
{
|
{
|
||||||
"name": "hostElement"
|
"name": "hostElement"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "initChangeDetectorIfExisting"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "inject"
|
"name": "inject"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1274,9 +1274,15 @@
|
||||||
{
|
{
|
||||||
"name": "couldBeInjectableType"
|
"name": "couldBeInjectableType"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createContainerRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createDirectivesAndLocals"
|
"name": "createDirectivesAndLocals"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createElementRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createEmbeddedViewAndNode"
|
"name": "createEmbeddedViewAndNode"
|
||||||
},
|
},
|
||||||
|
@ -1325,6 +1331,9 @@
|
||||||
{
|
{
|
||||||
"name": "createTView"
|
"name": "createTView"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createTemplateRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createTextNode"
|
"name": "createTextNode"
|
||||||
},
|
},
|
||||||
|
@ -1334,6 +1343,9 @@
|
||||||
{
|
{
|
||||||
"name": "createViewQuery"
|
"name": "createViewQuery"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createViewRef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dateGetter"
|
"name": "dateGetter"
|
||||||
},
|
},
|
||||||
|
@ -1706,18 +1718,6 @@
|
||||||
{
|
{
|
||||||
"name": "getNumberOfCurrencyDigits"
|
"name": "getNumberOfCurrencyDigits"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "getOrCreateChangeDetectorRef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getOrCreateContainerRef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getOrCreateElementRef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getOrCreateHostChangeDetector"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "getOrCreateInjectable"
|
"name": "getOrCreateInjectable"
|
||||||
},
|
},
|
||||||
|
@ -1733,9 +1733,6 @@
|
||||||
{
|
{
|
||||||
"name": "getOrCreateTView"
|
"name": "getOrCreateTView"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "getOrCreateTemplateRef"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "getOriginalError"
|
"name": "getOriginalError"
|
||||||
},
|
},
|
||||||
|
@ -1844,9 +1841,6 @@
|
||||||
{
|
{
|
||||||
"name": "identity"
|
"name": "identity"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "initChangeDetectorIfExisting"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "initDomAdapter"
|
"name": "initDomAdapter"
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,17 +11,18 @@ import {RenderFlags} from '@angular/core/src/render3/interfaces/definition';
|
||||||
|
|
||||||
import {defineComponent} from '../../src/render3/definition';
|
import {defineComponent} from '../../src/render3/definition';
|
||||||
import {bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
import {bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
||||||
import {NgOnChangesFeature, PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectRenderer2, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
import {PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectRenderer2, injectTemplateRef, injectViewContainerRef, load} from '../../src/render3/index';
|
||||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, loadDirective, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, loadDirective, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
||||||
import {LInjector} from '../../src/render3/interfaces/injector';
|
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||||
import {isProceduralRenderer} from '../../src/render3/interfaces/renderer';
|
import {isProceduralRenderer} from '../../src/render3/interfaces/renderer';
|
||||||
import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
|
import {AttributeMarker, LContainerNode, LElementNode, TNodeType} from '../../src/render3/interfaces/node';
|
||||||
|
|
||||||
import {LViewFlags} from '../../src/render3/interfaces/view';
|
import {LViewFlags} from '../../src/render3/interfaces/view';
|
||||||
import {ViewRef} from '../../src/render3/view_ref';
|
import {ViewRef} from '../../src/render3/view_ref';
|
||||||
|
|
||||||
import {getRendererFactory2} from './imported_renderer2';
|
import {getRendererFactory2} from './imported_renderer2';
|
||||||
import {ComponentFixture, createComponent, createDirective, renderComponent, toHtml} from './render_util';
|
import {ComponentFixture, createComponent, createDirective, renderComponent, toHtml} from './render_util';
|
||||||
|
import {NgIf} from './common_with_def';
|
||||||
|
|
||||||
describe('di', () => {
|
describe('di', () => {
|
||||||
describe('no dependencies', () => {
|
describe('no dependencies', () => {
|
||||||
|
@ -787,6 +788,10 @@ describe('di', () => {
|
||||||
|
|
||||||
describe('ElementRef', () => {
|
describe('ElementRef', () => {
|
||||||
it('should create directive with ElementRef dependencies', () => {
|
it('should create directive with ElementRef dependencies', () => {
|
||||||
|
let dir !: Directive;
|
||||||
|
let dirSameInstance !: DirectiveSameInstance;
|
||||||
|
let divNode !: LElementNode;
|
||||||
|
|
||||||
class Directive {
|
class Directive {
|
||||||
value: string;
|
value: string;
|
||||||
constructor(public elementRef: ElementRef) {
|
constructor(public elementRef: ElementRef) {
|
||||||
|
@ -795,47 +800,75 @@ describe('di', () => {
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: Directive,
|
type: Directive,
|
||||||
selectors: [['', 'dir', '']],
|
selectors: [['', 'dir', '']],
|
||||||
factory: () => new Directive(injectElementRef()),
|
factory: () => dir = new Directive(injectElementRef()),
|
||||||
features: [PublicFeature],
|
features: [PublicFeature],
|
||||||
exportAs: 'dir'
|
exportAs: 'dir'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class DirectiveSameInstance {
|
class DirectiveSameInstance {
|
||||||
value: boolean;
|
isSameInstance: boolean;
|
||||||
constructor(elementRef: ElementRef, directive: Directive) {
|
constructor(public elementRef: ElementRef, directive: Directive) {
|
||||||
this.value = (elementRef === directive.elementRef) && elementRef instanceof ElementRef;
|
this.isSameInstance = elementRef === directive.elementRef;
|
||||||
}
|
}
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: DirectiveSameInstance,
|
type: DirectiveSameInstance,
|
||||||
selectors: [['', 'dirSame', '']],
|
selectors: [['', 'dirSame', '']],
|
||||||
factory: () => new DirectiveSameInstance(injectElementRef(), directiveInject(Directive)),
|
factory: () => dirSameInstance =
|
||||||
|
new DirectiveSameInstance(injectElementRef(), directiveInject(Directive)),
|
||||||
exportAs: 'dirSame'
|
exportAs: 'dirSame'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** <div dir dirSame></div> */
|
||||||
* <div dir dirSame #dirSame="dirSame" #dir="dir">
|
|
||||||
* {{ dir.value }} - {{ dirSame.value }}
|
|
||||||
* </div>
|
|
||||||
*/
|
|
||||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dirSame', 'dirSame', 'dir', 'dir']);
|
elementStart(0, 'div', ['dir', '', 'dirSame', '']);
|
||||||
{ text(3); }
|
|
||||||
elementEnd();
|
elementEnd();
|
||||||
|
divNode = load(0);
|
||||||
}
|
}
|
||||||
|
}, 1, 0, [Directive, DirectiveSameInstance]);
|
||||||
if (rf & RenderFlags.Update) {
|
|
||||||
const tmp1 = reference(1) as any;
|
|
||||||
const tmp2 = reference(2) as any;
|
|
||||||
textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, ''));
|
|
||||||
}
|
|
||||||
}, 4, 2, [Directive, DirectiveSameInstance]);
|
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
const fixture = new ComponentFixture(App);
|
||||||
expect(fixture.html).toEqual('<div dir="" dirsame="">ElementRef-true</div>');
|
expect(dir.value).toEqual('ElementRef');
|
||||||
|
expect(dir.elementRef.nativeElement).toEqual(divNode.native);
|
||||||
|
expect(dirSameInstance.elementRef.nativeElement).toEqual(divNode.native);
|
||||||
|
|
||||||
|
// Each ElementRef instance should be unique
|
||||||
|
expect(dirSameInstance.isSameInstance).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create ElementRef with comment if requesting directive is on <ng-template> node',
|
||||||
|
() => {
|
||||||
|
let dir !: Directive;
|
||||||
|
let commentNode !: LContainerNode;
|
||||||
|
|
||||||
|
class Directive {
|
||||||
|
value: string;
|
||||||
|
constructor(public elementRef: ElementRef) {
|
||||||
|
this.value = (elementRef.constructor as any).name;
|
||||||
|
}
|
||||||
|
static ngDirectiveDef = defineDirective({
|
||||||
|
type: Directive,
|
||||||
|
selectors: [['', 'dir', '']],
|
||||||
|
factory: () => dir = new Directive(injectElementRef()),
|
||||||
|
features: [PublicFeature],
|
||||||
|
exportAs: 'dir'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** <ng-template dir></ng-template> */
|
||||||
|
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & RenderFlags.Create) {
|
||||||
|
template(0, () => {}, 0, 0, null, ['dir', '']);
|
||||||
|
commentNode = load(0);
|
||||||
|
}
|
||||||
|
}, 1, 0, [Directive]);
|
||||||
|
|
||||||
|
const fixture = new ComponentFixture(App);
|
||||||
|
expect(dir.value).toEqual('ElementRef');
|
||||||
|
expect(dir.elementRef.nativeElement).toEqual(commentNode.native);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('TemplateRef', () => {
|
describe('TemplateRef', () => {
|
||||||
|
@ -855,9 +888,9 @@ describe('di', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DirectiveSameInstance {
|
class DirectiveSameInstance {
|
||||||
value: boolean;
|
isSameInstance: boolean;
|
||||||
constructor(templateRef: TemplateRef<any>, directive: Directive) {
|
constructor(templateRef: TemplateRef<any>, directive: Directive) {
|
||||||
this.value = templateRef === directive.templateRef;
|
this.isSameInstance = templateRef === directive.templateRef;
|
||||||
}
|
}
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: DirectiveSameInstance,
|
type: DirectiveSameInstance,
|
||||||
|
@ -881,12 +914,13 @@ describe('di', () => {
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
const tmp1 = reference(1) as any;
|
const tmp1 = reference(1) as any;
|
||||||
const tmp2 = reference(2) as any;
|
const tmp2 = reference(2) as any;
|
||||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
|
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.isSameInstance, ''));
|
||||||
}
|
}
|
||||||
}, 4, 2, [Directive, DirectiveSameInstance]);
|
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
const fixture = new ComponentFixture(App);
|
||||||
expect(fixture.html).toEqual('TemplateRef-true');
|
// Each TemplateRef instance should be unique
|
||||||
|
expect(fixture.html).toEqual('TemplateRef-false');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -907,9 +941,9 @@ describe('di', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DirectiveSameInstance {
|
class DirectiveSameInstance {
|
||||||
value: boolean;
|
isSameInstance: boolean;
|
||||||
constructor(viewContainerRef: ViewContainerRef, directive: Directive) {
|
constructor(viewContainerRef: ViewContainerRef, directive: Directive) {
|
||||||
this.value = viewContainerRef === directive.viewContainerRef;
|
this.isSameInstance = viewContainerRef === directive.viewContainerRef;
|
||||||
}
|
}
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: DirectiveSameInstance,
|
type: DirectiveSameInstance,
|
||||||
|
@ -934,12 +968,13 @@ describe('di', () => {
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
const tmp1 = reference(1) as any;
|
const tmp1 = reference(1) as any;
|
||||||
const tmp2 = reference(2) as any;
|
const tmp2 = reference(2) as any;
|
||||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
|
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.isSameInstance, ''));
|
||||||
}
|
}
|
||||||
}, 4, 2, [Directive, DirectiveSameInstance]);
|
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
const fixture = new ComponentFixture(App);
|
||||||
expect(fixture.html).toEqual('<div dir="" dirsame="">ViewContainerRef-true</div>');
|
// Each ViewContainerRef instance should be unique
|
||||||
|
expect(fixture.html).toEqual('<div dir="" dirsame="">ViewContainerRef-false</div>');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -990,53 +1025,33 @@ describe('di', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class IfDirective {
|
const directives = [MyComp, Directive, DirectiveSameInstance, NgIf];
|
||||||
/* @Input */
|
|
||||||
myIf = true;
|
|
||||||
|
|
||||||
constructor(public template: TemplateRef<any>, public vcr: ViewContainerRef) {}
|
it('should inject current component ChangeDetectorRef into directives on the same node as components',
|
||||||
|
() => {
|
||||||
|
/** <my-comp dir dirSameInstance #dir="dir"></my-comp> {{ dir.value }} */
|
||||||
|
const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
|
||||||
|
if (rf & RenderFlags.Create) {
|
||||||
|
element(0, 'my-comp', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||||
|
text(2);
|
||||||
|
}
|
||||||
|
if (rf & RenderFlags.Update) {
|
||||||
|
const tmp = reference(1) as any;
|
||||||
|
textBinding(2, bind(tmp.value));
|
||||||
|
}
|
||||||
|
}, 3, 1, directives);
|
||||||
|
|
||||||
ngOnChanges() {
|
const app = renderComponent(MyApp);
|
||||||
if (this.myIf) {
|
// ChangeDetectorRef is the token, ViewRef has historically been the constructor
|
||||||
this.vcr.createEmbeddedView(this.template);
|
expect(toHtml(app)).toEqual('<my-comp dir="" dirsame=""></my-comp>ViewRef');
|
||||||
}
|
expect((comp !.cdr as ViewRef<MyComp>).context).toBe(comp);
|
||||||
}
|
|
||||||
|
|
||||||
static ngDirectiveDef = defineDirective({
|
// Each ChangeDetectorRef instance should be unique
|
||||||
type: IfDirective,
|
expect(dir !.cdr).not.toBe(comp !.cdr);
|
||||||
selectors: [['', 'myIf', '']],
|
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||||
factory: () => new IfDirective(injectTemplateRef(), injectViewContainerRef()),
|
});
|
||||||
inputs: {myIf: 'myIf'},
|
|
||||||
features: [PublicFeature, NgOnChangesFeature]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
it('should inject host component ChangeDetectorRef into directives on normal elements', () => {
|
||||||
const directives = [MyComp, Directive, DirectiveSameInstance, IfDirective];
|
|
||||||
|
|
||||||
it('should inject current component ChangeDetectorRef into directives on components', () => {
|
|
||||||
/** <my-comp dir dirSameInstance #dir="dir"></my-comp> {{ dir.value }} */
|
|
||||||
const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & RenderFlags.Create) {
|
|
||||||
element(0, 'my-comp', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
|
||||||
text(2);
|
|
||||||
}
|
|
||||||
if (rf & RenderFlags.Update) {
|
|
||||||
const tmp = reference(1) as any;
|
|
||||||
textBinding(2, bind(tmp.value));
|
|
||||||
}
|
|
||||||
}, 3, 1, directives);
|
|
||||||
|
|
||||||
const app = renderComponent(MyApp);
|
|
||||||
// ChangeDetectorRef is the token, ViewRef has historically been the constructor
|
|
||||||
expect(toHtml(app)).toEqual('<my-comp dir="" dirsame=""></my-comp>ViewRef');
|
|
||||||
expect((comp !.cdr as ViewRef<MyComp>).context).toBe(comp);
|
|
||||||
|
|
||||||
expect(dir !.cdr).toBe(comp !.cdr);
|
|
||||||
expect(dir !.cdr).toBe(dirSameInstance !.cdr);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject host component ChangeDetectorRef into directives on elements', () => {
|
|
||||||
|
|
||||||
class MyApp {
|
class MyApp {
|
||||||
constructor(public cdr: ChangeDetectorRef) {}
|
constructor(public cdr: ChangeDetectorRef) {}
|
||||||
|
@ -1067,49 +1082,52 @@ describe('di', () => {
|
||||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||||
|
|
||||||
expect(dir !.cdr).toBe(app.cdr);
|
// Each ChangeDetectorRef instance should be unique
|
||||||
expect(dir !.cdr).toBe(dirSameInstance !.cdr);
|
expect(dir !.cdr).not.toBe(app.cdr);
|
||||||
|
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject host component ChangeDetectorRef into directives in ContentChildren', () => {
|
it('should inject host component ChangeDetectorRef into directives in a component\'s ContentChildren',
|
||||||
class MyApp {
|
() => {
|
||||||
constructor(public cdr: ChangeDetectorRef) {}
|
class MyApp {
|
||||||
|
constructor(public cdr: ChangeDetectorRef) {}
|
||||||
|
|
||||||
static ngComponentDef = defineComponent({
|
static ngComponentDef = defineComponent({
|
||||||
type: MyApp,
|
type: MyApp,
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 4,
|
consts: 4,
|
||||||
vars: 1,
|
vars: 1,
|
||||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||||
/**
|
/**
|
||||||
* <my-comp>
|
* <my-comp>
|
||||||
* <div dir dirSameInstance #dir="dir"></div>
|
* <div dir dirSameInstance #dir="dir"></div>
|
||||||
* </my-comp>
|
* </my-comp>
|
||||||
* {{ dir.value }}
|
* {{ dir.value }}
|
||||||
*/
|
*/
|
||||||
template: function(rf: RenderFlags, ctx: any) {
|
template: function(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'my-comp');
|
elementStart(0, 'my-comp');
|
||||||
{ element(1, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); }
|
{ element(1, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); }
|
||||||
elementEnd();
|
elementEnd();
|
||||||
text(3);
|
text(3);
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
const tmp = reference(2) as any;
|
const tmp = reference(2) as any;
|
||||||
textBinding(3, bind(tmp.value));
|
textBinding(3, bind(tmp.value));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
directives: directives
|
directives: directives
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = renderComponent(MyApp);
|
const app = renderComponent(MyApp);
|
||||||
expect(toHtml(app)).toEqual('<my-comp><div dir="" dirsame=""></div></my-comp>ViewRef');
|
expect(toHtml(app)).toEqual('<my-comp><div dir="" dirsame=""></div></my-comp>ViewRef');
|
||||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||||
|
|
||||||
expect(dir !.cdr).toBe(app !.cdr);
|
// Each ChangeDetectorRef instance should be unique
|
||||||
expect(dir !.cdr).toBe(dirSameInstance !.cdr);
|
expect(dir !.cdr).not.toBe(app !.cdr);
|
||||||
});
|
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||||
|
});
|
||||||
|
|
||||||
it('should inject host component ChangeDetectorRef into directives in embedded views', () => {
|
it('should inject host component ChangeDetectorRef into directives in embedded views', () => {
|
||||||
|
|
||||||
|
@ -1161,8 +1179,9 @@ describe('di', () => {
|
||||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||||
|
|
||||||
expect(dir !.cdr).toBe(app.cdr);
|
// Each ChangeDetectorRef instance should be unique
|
||||||
expect(dir !.cdr).toBe(dirSameInstance !.cdr);
|
expect(dir !.cdr).not.toBe(app.cdr);
|
||||||
|
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject host component ChangeDetectorRef into directives on containers', () => {
|
it('should inject host component ChangeDetectorRef into directives on containers', () => {
|
||||||
|
@ -1189,10 +1208,10 @@ describe('di', () => {
|
||||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 0,
|
vars: 0,
|
||||||
/** <div *myIf="showing" dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */
|
/** <div *ngIf="showing" dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */
|
||||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
template(0, C1, 3, 1, null, ['myIf', 'showing']);
|
template(0, C1, 3, 1, null, ['ngIf', 'showing']);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
directives: directives
|
directives: directives
|
||||||
|
@ -1203,8 +1222,9 @@ describe('di', () => {
|
||||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||||
|
|
||||||
expect(dir !.cdr).toBe(app.cdr);
|
// Each ChangeDetectorRef instance should be unique
|
||||||
expect(dir !.cdr).toBe(dirSameInstance !.cdr);
|
expect(dir !.cdr).not.toBe(app.cdr);
|
||||||
|
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||||
import {RenderFlags} from '@angular/core/src/render3';
|
import {RenderFlags} from '@angular/core/src/render3';
|
||||||
|
|
||||||
import {RendererStyleFlags2, RendererType2} from '../../src/render/api';
|
import {RendererStyleFlags2, RendererType2} from '../../src/render/api';
|
||||||
import {getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from '../../src/render3/di';
|
import {createTemplateRef, getOrCreateNodeInjectorForNode} from '../../src/render3/di';
|
||||||
import {AttributeMarker, defineComponent, defineDirective, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
import {AttributeMarker, defineComponent, defineDirective, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||||
|
|
||||||
import {NO_CHANGE, bind, container, containerRefreshEnd, containerRefreshStart, element, elementAttribute, elementClassProp, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, elementStyleProp, elementStyling, elementStylingApply, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV, listener, load, loadDirective, projection, projectionDef, text, textBinding, template} from '../../src/render3/instructions';
|
import {NO_CHANGE, bind, container, containerRefreshEnd, containerRefreshStart, element, elementAttribute, elementClassProp, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, elementStyleProp, elementStyling, elementStylingApply, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV, listener, load, loadDirective, projection, projectionDef, text, textBinding, template} from '../../src/render3/instructions';
|
||||||
|
|
Loading…
Reference in New Issue