Skip to content

Commit 1c3226d

Browse files
mheveryatscott
authored andcommitted
refactor(core): Cleanup circular dependency between ViewEngine and Ivy TemplateRef. (#39710)
`TemplateRef` is declared in ViewEngine but it sub-classed in Ivy. This creates a circular dependency between ViewEngine `TemplateRef` which needs to declare `__NG_ELEMENT_ID__` and ivy factory which needs to create it. The workaround used to be to pass the `TemplateRef` through stack but that created a very convoluted code. This refactoring simply bundles the two files together and removes the stack workaround making the code simpler to follow. PR Close #39710
1 parent 5080a16 commit 1c3226d

File tree

10 files changed

+169
-117
lines changed

10 files changed

+169
-117
lines changed

goldens/circular-deps/packages.json

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,14 @@
273273
"packages/core/src/change_detection/change_detection.ts",
274274
"packages/core/src/change_detection/change_detector_ref.ts",
275275
"packages/core/src/render3/view_engine_compatibility.ts",
276-
"packages/core/src/linker/view_container_ref.ts",
276+
"packages/core/src/linker/template_ref.ts",
277+
"packages/core/src/render3/instructions/shared.ts",
278+
"packages/core/src/di.ts",
279+
"packages/core/src/di/index.ts",
280+
"packages/core/src/di/injectable.ts",
281+
"packages/core/src/di/jit/injectable.ts",
282+
"packages/core/src/di/jit/environment.ts",
283+
"packages/core/src/di/injector_compatibility.ts",
277284
"packages/core/src/di/injector.ts",
278285
"packages/core/src/di/r3_injector.ts",
279286
"packages/core/src/render3/definition.ts",
@@ -286,7 +293,16 @@
286293
"packages/core/src/change_detection/change_detection.ts",
287294
"packages/core/src/change_detection/change_detector_ref.ts",
288295
"packages/core/src/render3/view_engine_compatibility.ts",
289-
"packages/core/src/render3/di.ts",
296+
"packages/core/src/linker/template_ref.ts",
297+
"packages/core/src/render3/instructions/shared.ts",
298+
"packages/core/src/error_handler.ts",
299+
"packages/core/src/errors.ts",
300+
"packages/core/src/view/types.ts",
301+
"packages/core/src/di.ts",
302+
"packages/core/src/di/index.ts",
303+
"packages/core/src/di/injectable.ts",
304+
"packages/core/src/di/jit/injectable.ts",
305+
"packages/core/src/di/jit/environment.ts",
290306
"packages/core/src/di/injector_compatibility.ts",
291307
"packages/core/src/di/injector.ts",
292308
"packages/core/src/di/r3_injector.ts",
@@ -300,7 +316,12 @@
300316
"packages/core/src/change_detection/change_detection.ts",
301317
"packages/core/src/change_detection/change_detector_ref.ts",
302318
"packages/core/src/render3/view_engine_compatibility.ts",
303-
"packages/core/src/render3/di.ts",
319+
"packages/core/src/linker/template_ref.ts",
320+
"packages/core/src/render3/instructions/shared.ts",
321+
"packages/core/src/error_handler.ts",
322+
"packages/core/src/errors.ts",
323+
"packages/core/src/view/types.ts",
324+
"packages/core/src/linker/view_container_ref.ts",
304325
"packages/core/src/di/injector.ts",
305326
"packages/core/src/di/r3_injector.ts",
306327
"packages/core/src/render3/definition.ts",
@@ -313,7 +334,8 @@
313334
"packages/core/src/change_detection/change_detection.ts",
314335
"packages/core/src/change_detection/change_detector_ref.ts",
315336
"packages/core/src/render3/view_engine_compatibility.ts",
316-
"packages/core/src/render3/di.ts",
337+
"packages/core/src/linker/template_ref.ts",
338+
"packages/core/src/render3/instructions/shared.ts",
317339
"packages/core/src/render3/definition.ts",
318340
"packages/core/src/metadata/ng_module.ts"
319341
],
@@ -324,12 +346,9 @@
324346
"packages/core/src/change_detection/change_detection.ts",
325347
"packages/core/src/change_detection/change_detector_ref.ts",
326348
"packages/core/src/render3/view_engine_compatibility.ts",
349+
"packages/core/src/linker/template_ref.ts",
327350
"packages/core/src/render3/instructions/shared.ts",
328-
"packages/core/src/di.ts",
329-
"packages/core/src/di/index.ts",
330-
"packages/core/src/di/injectable.ts",
331-
"packages/core/src/di/jit/injectable.ts",
332-
"packages/core/src/di/jit/environment.ts",
351+
"packages/core/src/render3/di.ts",
333352
"packages/core/src/di/injector_compatibility.ts",
334353
"packages/core/src/di/injector.ts",
335354
"packages/core/src/di/r3_injector.ts",
@@ -343,16 +362,9 @@
343362
"packages/core/src/change_detection/change_detection.ts",
344363
"packages/core/src/change_detection/change_detector_ref.ts",
345364
"packages/core/src/render3/view_engine_compatibility.ts",
365+
"packages/core/src/linker/template_ref.ts",
346366
"packages/core/src/render3/instructions/shared.ts",
347-
"packages/core/src/error_handler.ts",
348-
"packages/core/src/errors.ts",
349-
"packages/core/src/view/types.ts",
350-
"packages/core/src/di.ts",
351-
"packages/core/src/di/index.ts",
352-
"packages/core/src/di/injectable.ts",
353-
"packages/core/src/di/jit/injectable.ts",
354-
"packages/core/src/di/jit/environment.ts",
355-
"packages/core/src/di/injector_compatibility.ts",
367+
"packages/core/src/render3/di.ts",
356368
"packages/core/src/di/injector.ts",
357369
"packages/core/src/di/r3_injector.ts",
358370
"packages/core/src/render3/definition.ts",
@@ -365,7 +377,9 @@
365377
"packages/core/src/change_detection/change_detection.ts",
366378
"packages/core/src/change_detection/change_detector_ref.ts",
367379
"packages/core/src/render3/view_engine_compatibility.ts",
380+
"packages/core/src/linker/template_ref.ts",
368381
"packages/core/src/render3/instructions/shared.ts",
382+
"packages/core/src/render3/di.ts",
369383
"packages/core/src/render3/definition.ts",
370384
"packages/core/src/metadata/ng_module.ts"
371385
],
@@ -376,6 +390,7 @@
376390
"packages/core/src/change_detection/change_detection.ts",
377391
"packages/core/src/change_detection/change_detector_ref.ts",
378392
"packages/core/src/render3/view_engine_compatibility.ts",
393+
"packages/core/src/linker/template_ref.ts",
379394
"packages/core/src/render3/instructions/shared.ts",
380395
"packages/core/src/render3/instructions/lview_debug.ts",
381396
"packages/core/src/core.ts",
@@ -398,6 +413,7 @@
398413
"packages/core/src/change_detection/change_detection.ts",
399414
"packages/core/src/change_detection/change_detector_ref.ts",
400415
"packages/core/src/render3/view_engine_compatibility.ts",
416+
"packages/core/src/linker/template_ref.ts",
401417
"packages/core/src/render3/view_ref.ts"
402418
],
403419
[
@@ -849,17 +865,23 @@
849865
"packages/core/src/change_detection/change_detection.ts",
850866
"packages/core/src/change_detection/change_detector_ref.ts",
851867
"packages/core/src/render3/view_engine_compatibility.ts",
852-
"packages/core/src/linker/view_container_ref.ts",
868+
"packages/core/src/linker/template_ref.ts",
869+
"packages/core/src/render3/instructions/shared.ts",
870+
"packages/core/src/error_handler.ts",
871+
"packages/core/src/errors.ts",
872+
"packages/core/src/view/types.ts",
853873
"packages/core/src/linker/component_factory.ts"
854874
],
855875
[
856876
"packages/core/src/change_detection/change_detection.ts",
857877
"packages/core/src/change_detection/change_detector_ref.ts",
858878
"packages/core/src/render3/view_engine_compatibility.ts",
879+
"packages/core/src/linker/template_ref.ts",
859880
"packages/core/src/render3/instructions/shared.ts",
860881
"packages/core/src/error_handler.ts",
861882
"packages/core/src/errors.ts",
862883
"packages/core/src/view/types.ts",
884+
"packages/core/src/linker/view_container_ref.ts",
863885
"packages/core/src/linker/component_factory.ts"
864886
],
865887
[
@@ -878,6 +900,7 @@
878900
[
879901
"packages/core/src/change_detection/change_detector_ref.ts",
880902
"packages/core/src/render3/view_engine_compatibility.ts",
903+
"packages/core/src/linker/template_ref.ts",
881904
"packages/core/src/render3/view_ref.ts"
882905
],
883906
[
@@ -928,6 +951,30 @@
928951
"packages/core/src/errors.ts",
929952
"packages/core/src/view/types.ts"
930953
],
954+
[
955+
"packages/core/src/error_handler.ts",
956+
"packages/core/src/errors.ts",
957+
"packages/core/src/view/types.ts",
958+
"packages/core/src/linker/template_ref.ts",
959+
"packages/core/src/render3/instructions/shared.ts"
960+
],
961+
[
962+
"packages/core/src/error_handler.ts",
963+
"packages/core/src/errors.ts",
964+
"packages/core/src/view/types.ts",
965+
"packages/core/src/linker/view_container_ref.ts",
966+
"packages/core/src/linker/template_ref.ts",
967+
"packages/core/src/render3/instructions/shared.ts"
968+
],
969+
[
970+
"packages/core/src/error_handler.ts",
971+
"packages/core/src/errors.ts",
972+
"packages/core/src/view/types.ts",
973+
"packages/core/src/linker/view_container_ref.ts",
974+
"packages/core/src/render3/view_engine_compatibility.ts",
975+
"packages/core/src/linker/template_ref.ts",
976+
"packages/core/src/render3/instructions/shared.ts"
977+
],
931978
[
932979
"packages/core/src/linker/component_factory_resolver.ts",
933980
"packages/core/src/linker/ng_module_factory.ts"
@@ -943,14 +990,6 @@
943990
"packages/core/src/linker/ng_module_factory_registration.ts",
944991
"packages/core/src/render3/ng_module_ref.ts"
945992
],
946-
[
947-
"packages/core/src/linker/template_ref.ts",
948-
"packages/core/src/render3/view_engine_compatibility.ts"
949-
],
950-
[
951-
"packages/core/src/linker/view_container_ref.ts",
952-
"packages/core/src/render3/view_engine_compatibility.ts"
953-
],
954993
[
955994
"packages/core/src/metadata/directives.ts",
956995
"packages/core/src/render3/jit/directive.ts"

packages/core/src/linker/template_ref.ts

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,23 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {injectTemplateRef as render3InjectTemplateRef} from '../render3/view_engine_compatibility';
9+
import {assertLContainer} from '../render3/assert';
10+
import {createLView, renderView} from '../render3/instructions/shared';
11+
import {TContainerNode, TNode, TNodeType} from '../render3/interfaces/node';
12+
import {DECLARATION_LCONTAINER, LView, LViewFlags, QUERIES, TView} from '../render3/interfaces/view';
13+
import {getCurrentTNode, getLView} from '../render3/state';
14+
import {ViewRef as R3_ViewRef} from '../render3/view_ref';
15+
import {assertDefined} from '../util/assert';
1016
import {noop} from '../util/noop';
11-
12-
import {ElementRef} from './element_ref';
17+
import {createElementRef, ElementRef} from './element_ref';
1318
import {EmbeddedViewRef} from './view_ref';
1419

1520

21+
22+
export const SWITCH_TEMPLATE_REF_FACTORY__POST_R3__ = injectTemplateRef;
23+
const SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__ = noop;
24+
const SWITCH_TEMPLATE_REF_FACTORY: typeof injectTemplateRef = SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__;
25+
1626
/**
1727
* Represents an embedded template that can be used to instantiate embedded views.
1828
* To instantiate embedded views based on a template, use the `ViewContainerRef`
@@ -59,11 +69,60 @@ export abstract class TemplateRef<C> {
5969
* @internal
6070
* @nocollapse
6171
*/
62-
static __NG_ELEMENT_ID__:
63-
() => TemplateRef<any>| null = () => SWITCH_TEMPLATE_REF_FACTORY(TemplateRef)
72+
static __NG_ELEMENT_ID__: () => TemplateRef<any>| null = SWITCH_TEMPLATE_REF_FACTORY;
6473
}
6574

66-
export const SWITCH_TEMPLATE_REF_FACTORY__POST_R3__ = render3InjectTemplateRef;
67-
const SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__ = noop;
68-
const SWITCH_TEMPLATE_REF_FACTORY: typeof render3InjectTemplateRef =
69-
SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__;
75+
const ViewEngineTemplateRef = TemplateRef;
76+
77+
const R3TemplateRef = class TemplateRef<T> extends ViewEngineTemplateRef<T> {
78+
constructor(
79+
private _declarationLView: LView, private _declarationTContainer: TContainerNode,
80+
public elementRef: ElementRef) {
81+
super();
82+
}
83+
84+
createEmbeddedView(context: T): EmbeddedViewRef<T> {
85+
const embeddedTView = this._declarationTContainer.tViews as TView;
86+
const embeddedLView = createLView(
87+
this._declarationLView, embeddedTView, context, LViewFlags.CheckAlways, null,
88+
embeddedTView.declTNode, null, null, null, null);
89+
90+
const declarationLContainer = this._declarationLView[this._declarationTContainer.index];
91+
ngDevMode && assertLContainer(declarationLContainer);
92+
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
93+
94+
const declarationViewLQueries = this._declarationLView[QUERIES];
95+
if (declarationViewLQueries !== null) {
96+
embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
97+
}
98+
99+
renderView(embeddedTView, embeddedLView, context);
100+
101+
return new R3_ViewRef<T>(embeddedLView);
102+
}
103+
};
104+
105+
/**
106+
* Creates a TemplateRef given a node.
107+
*
108+
* @returns The TemplateRef instance to use
109+
*/
110+
export function injectTemplateRef<T>(): TemplateRef<T>|null {
111+
return createTemplateRef<T>(getCurrentTNode()!, getLView());
112+
}
113+
114+
/**
115+
* Creates a TemplateRef and stores it on the injector.
116+
*
117+
* @param hostTNode The node on which a TemplateRef is requested
118+
* @param hostLView The `LView` to which the node belongs
119+
* @returns The TemplateRef instance or null if we can't create a TemplateRef on a given node type
120+
*/
121+
export function createTemplateRef<T>(hostTNode: TNode, hostLView: LView): TemplateRef<T>|null {
122+
if (hostTNode.type & TNodeType.Container) {
123+
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
124+
return new R3TemplateRef(
125+
hostLView, hostTNode as TContainerNode, createElementRef(hostTNode, hostLView));
126+
}
127+
return null;
128+
}

packages/core/src/render3/query.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {InjectionToken} from '../di/injection_token';
1313
import {Type} from '../interface/type';
1414
import {createElementRef, ElementRef as ViewEngine_ElementRef} from '../linker/element_ref';
1515
import {QueryList} from '../linker/query_list';
16-
import {TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref';
16+
import {createTemplateRef, TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref';
1717
import {ViewContainerRef} from '../linker/view_container_ref';
1818
import {assertDefined, assertIndexInRange, throwError} from '../util/assert';
1919
import {stringify} from '../util/stringify';
@@ -30,7 +30,7 @@ import {DECLARATION_LCONTAINER, LView, PARENT, QUERIES, TVIEW, TView} from './in
3030
import {assertTNodeType} from './node_assert';
3131
import {getCurrentQueryIndex, getCurrentTNode, getLView, getTView, setCurrentQueryIndex} from './state';
3232
import {isCreationMode} from './util/view_utils';
33-
import {createContainerRef, createTemplateRef} from './view_engine_compatibility';
33+
import {createContainerRef} from './view_engine_compatibility';
3434

3535
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4;
3636

@@ -302,7 +302,7 @@ function createResultByTNodeType(tNode: TNode, currentView: LView): any {
302302
if (tNode.type & (TNodeType.AnyRNode | TNodeType.ElementContainer)) {
303303
return createElementRef(tNode, currentView);
304304
} else if (tNode.type & TNodeType.Container) {
305-
return createTemplateRef(ViewEngine_TemplateRef, tNode, currentView);
305+
return createTemplateRef(tNode, currentView);
306306
}
307307
return null;
308308
}
@@ -325,7 +325,7 @@ function createSpecialToken(lView: LView, tNode: TNode, read: any): any {
325325
if (read === ViewEngine_ElementRef) {
326326
return createElementRef(tNode, lView);
327327
} else if (read === ViewEngine_TemplateRef) {
328-
return createTemplateRef(ViewEngine_TemplateRef, tNode, lView);
328+
return createTemplateRef(tNode, lView);
329329
} else if (read === ViewContainerRef) {
330330
ngDevMode && assertTNodeType(tNode, TNodeType.AnyRNode | TNodeType.AnyContainer);
331331
return createContainerRef(

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy