0

Angular CLI: 8.3.26 // Angular: 8.2.14

I use a directive (open-chatpanel.diretive.ts) in order to create dynamic components.

Everything is ok except that : I can't figure out how to add it into a specific place ?!?

Here is the directive (open-chatpanel.diretive.ts)

import {
  Directive,
  HostListener,
  ComponentFactory,
  ComponentFactoryResolver,
  ViewChild,
  ViewContainerRef,
  ComponentRef
} from '@angular/core';

import { ChatpanelComponent } from "./chatpanel/chatpanel.component"; // The component to create


@Directive({
  selector: '[appOpenChatpanel]'
})
export class OpenChatpanelDirective {

  @ViewChild("chatpanelsContainer", { read: ViewContainerRef ,static: true }) container;

  open: boolean = false;  //open or not
  chatPanelRef: ComponentRef<ChatpanelComponent>;
  chatPanelFactory: ComponentFactory<ChatpanelComponent>;

  @HostListener('click') toggle() {
    if (open) { this.openChatpanel(); } else { this.closeChatpanel();}
  };

  constructor(
    private resolver: ComponentFactoryResolver,
    private viewContainerRef: ViewContainerRef
  ) {
    this.chatPanelFactory = this.resolver.resolveComponentFactory(ChatpanelComponent);
  }

  private openChatpanel() {

    this.chatPanelRef = this.container.createComponent(this.chatPanelFactory);
    this.open = true;
    this.chatPanelRef.instance.close.subscribe(() => {
      this.chatPanelRef.instance.close.unsubscribe();
      this.chatPanelRef.destroy();
      //this.viewContainerRef.clear();
      this.open = false;
    });
  }

  private closeChatpanel() {
    this.chatPanelRef.instance.close.next();
    // Do you magic here
  }

}

Here is the component using the directiv (appOpenChatpanel) and defining the place where dynamic components should be put (#chatpanelsContainer). (File: app.component.html)

<div class="container">
  <div class="row my-2" >
    <div class="col-4">
      <h2>UserList</h2>
      <ul class="list-group my-2">
        <li class="list-group-item" appOpenChatpanel >User 1</li>
        <li class="list-group-item" appOpenChatpanel >User 2 </li>
        <li class="list-group-item">
          <button (click)="destroyComponent()">[Remove]</button>
        </li>
      </ul>

    </div>
    <!-- NOTICE: #chatpanelsContainer : Template Var in order to be abble to target this area for creating new Components -->
    <div class="col-8">
      <ng-template #chatpanelsContainer></ng-template>
    </div>
  </div>
</div>

All I want to do is to put the new dynamic component into the

<ng-template #chatpanelsContainer></ng-template>

But I always get a message saying :

ERROR TypeError: "this.container is undefined"
    openChatpanel open-chatpanel.directive.ts:41

I don't understand how to get the ng-template #chatpanelsContainer as a ViewContainerRef so I can use it to insert my new components.

Can Someone help me please :) Stuff to read, answers, example, please help please help :) Can't wait to read you guys and girls. Thanks in advance.

Edit: tried to create a stackblitz (not sure it's well made) : https://angular-issue-repro2-vjhfrj.stackblitz.io

PampleBee
  • 11
  • 6
  • Should I use TemplateRef instead of ViewContainerRef ? since i red this article https://indepth.dev/exploring-angular-dom-manipulation-techniques-using-viewcontainerref/ it seems that : << But, it’s reversed for directives β€” they have no views and they usually work directly with the element they are attached to. >> so may be it's not possible tu use @ViewChild decorator for directiv ? Can someone confirm or infirm that ? – PampleBee Apr 01 '20 at 16:25
  • Using injection of ViewContainerRef in the constructor `constructor( private resolver: ComponentFactoryResolver, private viewContainerRef: ViewContainerRef ) {`. and creating the dynamic component with `this.chatPanelRef = this.viewContainerRef.createComponent(this.chatPanelFactory); ` I get new component created inside as sibling of the
  • inside the
      . By using injection (if needed) how can I still get my new component inside the template var I want to use ? How can I make my new components to be at the right place (I mean not in the
        section). Thanks in advance
  • – PampleBee Apr 01 '20 at 16:27