@@ -18,9 +18,9 @@ import {NgStaticData, LNodeStatic, LContainerStatic, InitialInputData, InitialIn
1818import { assertNodeType } from './node_assert' ;
1919import { appendChild , insertChild , insertView , processProjectedNode , removeView } from './node_manipulation' ;
2020import { isNodeMatchingSelector } from './node_selector_matcher' ;
21- import { ComponentDef , ComponentTemplate , DirectiveDef } from './public_interfaces' ;
21+ import { ComponentDef , ComponentTemplate , ComponentType , DirectiveDef } from './public_interfaces' ;
2222import { QueryList , QueryState_ } from './query' ;
23- import { RComment , RElement , RText , Renderer3 , ProceduralRenderer3 , ObjectOrientedRenderer3 , RendererStyleFlags3 } from './renderer' ;
23+ import { RComment , RElement , RText , Renderer3 , RendererFactory3 , ProceduralRenderer3 , ObjectOrientedRenderer3 , RendererStyleFlags3 } from './renderer' ;
2424import { isDifferent , stringify } from './util' ;
2525
2626export { queryRefresh } from './query' ;
@@ -73,6 +73,7 @@ let nextNgElementId = 0;
7373 * Renderer2.
7474 */
7575let renderer : Renderer3 ;
76+ let rendererFactory : RendererFactory3 ;
7677
7778/** Used to set the parent property when nodes are created. */
7879let previousOrParentNode : LNode ;
@@ -278,18 +279,44 @@ export function createLNode(
278279/**
279280 *
280281 * @param host Existing node to render into.
281- * @param renderer Renderer to use.
282282 * @param template Template function with the instructions.
283283 * @param context to pass into the template.
284284 */
285- export function renderTemplate < T > ( host : LElement , template : ComponentTemplate < T > , context : T ) {
285+ export function renderTemplate < T > (
286+ hostNode : RElement , template : ComponentTemplate < T > , context : T ,
287+ providedRendererFactory : RendererFactory3 , host : LElement | null ) : LElement {
288+ if ( host == null ) {
289+ rendererFactory = providedRendererFactory ;
290+ host = createLNode (
291+ null , LNodeFlags . Element , hostNode ,
292+ createViewState ( - 1 , providedRendererFactory . createRenderer ( null , null ) , [ ] ) ) ;
293+ }
286294 const hostView = host . data ! ;
287295 ngDevMode && assertNotEqual ( hostView , null , 'hostView' ) ;
288296 hostView . ngStaticData = getTemplateStatic ( template ) ;
289- const oldView = enterView ( hostView , host ) ;
297+ renderComponentOrTemplate ( host , hostView , context , template ) ;
298+ return host ;
299+ }
300+
301+ export function renderComponentOrTemplate < T > (
302+ node : LElement , viewState : ViewState , componentOrContext : T , template ?: ComponentTemplate < T > ) {
303+ const oldView = enterView ( viewState , node ) ;
290304 try {
291- template ( context , creationMode ) ;
305+ if ( rendererFactory . begin ) {
306+ rendererFactory . begin ( ) ;
307+ }
308+ if ( template ) {
309+ ngStaticData = template . ngStaticData || ( template . ngStaticData = [ ] as never ) ;
310+ template ( componentOrContext ! , creationMode ) ;
311+ } else {
312+ // Element was stored at 0 and directive was stored at 1 in renderComponent
313+ // so to refresh the component, r() needs to be called with (1, 0)
314+ ( componentOrContext . constructor as ComponentType < T > ) . ngComponentDef . r ( 1 , 0 ) ;
315+ }
292316 } finally {
317+ if ( rendererFactory . end ) {
318+ rendererFactory . end ( ) ;
319+ }
293320 leaveView ( oldView ) ;
294321 }
295322}
@@ -406,7 +433,10 @@ export function elementStart(
406433 let componentView : ViewState | null = null ;
407434 if ( isHostElement ) {
408435 const ngStaticData = getTemplateStatic ( ( nameOrComponentDef as ComponentDef < any > ) . template ) ;
409- componentView = addToViewTree ( createViewState ( - 1 , renderer , ngStaticData ) ) ;
436+ componentView = addToViewTree ( createViewState (
437+ - 1 , rendererFactory . createRenderer (
438+ native , ( nameOrComponentDef as ComponentDef < any > ) . rendererType ) ,
439+ ngStaticData ) ) ;
410440 }
411441
412442 // Only component views should be added to the view tree directly. Embedded views are
@@ -453,16 +483,19 @@ export function createError(text: string, token: any) {
453483
454484
455485/**
456- * Used for bootstrapping existing nodes into rendering pipeline.
486+ * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
457487 *
458488 * @param elementOrSelector Render element or CSS selector to locate the element.
459489 */
460- export function elementHost ( elementOrSelector : RElement | string , def : ComponentDef < any > ) {
490+ export function locateHostElement (
491+ factory : RendererFactory3 , elementOrSelector : RElement | string ) : RElement | null {
461492 ngDevMode && assertDataInRange ( - 1 ) ;
493+ rendererFactory = factory ;
494+ const defaultRenderer = factory . createRenderer ( null , null ) ;
462495 const rNode = typeof elementOrSelector === 'string' ?
463- ( ( renderer as ProceduralRenderer3 ) . selectRootElement ?
464- ( renderer as ProceduralRenderer3 ) . selectRootElement ( elementOrSelector ) :
465- ( renderer as ObjectOrientedRenderer3 ) . querySelector ! ( elementOrSelector ) ) :
496+ ( ( defaultRenderer as ProceduralRenderer3 ) . selectRootElement ?
497+ ( defaultRenderer as ProceduralRenderer3 ) . selectRootElement ( elementOrSelector ) :
498+ ( defaultRenderer as ObjectOrientedRenderer3 ) . querySelector ! ( elementOrSelector ) ) :
466499 elementOrSelector ;
467500 if ( ngDevMode && ! rNode ) {
468501 if ( typeof elementOrSelector === 'string' ) {
@@ -471,6 +504,15 @@ export function elementHost(elementOrSelector: RElement | string, def: Component
471504 throw createError ( 'Host node is required:' , elementOrSelector ) ;
472505 }
473506 }
507+ return rNode ;
508+ }
509+
510+ /**
511+ * Creates the host LNode..
512+ *
513+ * @param rNode Render host element.
514+ */
515+ export function hostElement ( rNode : RElement | null , def : ComponentDef < any > ) {
474516 createLNode (
475517 0 , LNodeFlags . Element , rNode , createViewState ( - 1 , renderer , getTemplateStatic ( def . template ) ) ) ;
476518}
0 commit comments