Skip to content

Refactor DynamicComponentLoader/Compiler/Renderer to support user views and make them more consistent #1351

@tbosch

Description

@tbosch
  1. Realization: bootstrap is the same as inserting an ng component into a user render view

    Both start with code that has a plain DOM element and want to
    add an ng component there

  2. We should really separate compilation from instantiation of ProtoViews when we load dynamic components so that instantiation can happen in sync.

  3. compileRoot(element) is wrong as the protoView cannot be used multiple times

    Instead: compileWithHost(type): ProtoView
    AND creating render views with inserting them at the same time
    E.g.

    • renderer.createViewInViewContainer(viewContainerRef, atIndex, protoViewRef):List<ViewRef>
      • used with: compile.compileWithHost(Type)
      • used with: SubProtoView
    • renderer.createComponentView(hostViewRef, boundElementIndex, protoViewRef):List<ViewRef>
      • used with: compile.compile(Type)
    • renderer.becomeHostView(parentViewRef, renderLocation, protoViewRef):List<ViewRef>
      • used with: `compile.compileWithHost(Type);

    This works as we don't create RenderViews until we hydrate on the app side!
    With this, the renderer can e.g. not clone for renderer.createViewInUserView, but
    use the element at the given location, while the ProtoView is still reusable

    Nice side benefit: as soon as render views are hydrated, they are guaranteed
    to know their parent views.

Use case: Add new view to ViewContainer

  1. ViewContainer.create()
    • renderer.createViewInViewContainer
    • appView.hydrate(renderViewRefs)

Use case: Dynamic components

  1. Compiler.compile(Type):Promise<ProtoView>
  2. DynamicComponentLoader.loadIntoNgView(protoView):ComponentRef
    • renderer.createComponentViewInNgView
    • appView.hydrate(renderViewRefs)

Use case: Overlay components
(assuming a dynamic ViewContainer as discussed)

  1. Compiler.compileWithHost(Type, serviceBindings):Promise<ProtoView>
    provide the service bindings already in the compile call,
    so that the ProtoView can be used later in a ViewContainer!
    (i.e. add ViewContainer.create(protoView) -> for overlay components!)
  2. ViewContainer.create(protoView)
    see above

Use case: Ng components in User views and bootstrap:

  1. Compiler.compileWithHost(Type, serviceBindings):Promise<ProtoView>
  2. DynamicComponentLoader.loadIntoUserView(parentViewRef, renderLocation, protoView):ComponentRef
    • renderer.createComponentViewInUserView(renderLocation, protoViewRef)
    • appView.hydrate(renderViewRefs)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions