Угловой динамический компонент с ng-шаблоном

#angular #ng-template #angular-dynamic-components

#угловой #ng-template #угловые динамические компоненты

Вопрос:

Компонент с ng-template

 @Component({
  template: `
    <div>Hello Component is here!</div>

    <ng-template #cmp_anchor>
      <div>Template content</div>
    </ng-template>
  `,
})
export class HelloComponent {}
  

При визуализации с помощью ngTemplateOutlet нет доступа к ng-template

 @Component({
  selector: 'my-app',
  template: `
    <ng-container *ngComponentOutlet="helloComponent"></ng-container>

    <ng-container
      [ngTemplateOutlet]="cmpTemplateRef">
    </ng-container>
  `
})
export class AppComponent  {
  public helloComponent = HelloComponent;

  @ContentChild('cmp_anchor', {read: TemplateRef}) cmpTemplateRef: TemplateRef<any>;
}
  

Пример кода на: https://stackblitz.com/edit/angular-ng-component-outlet-with-ng-template?embed=1amp;file=src/app/app.component.ts

Ответ №1:

Это действительно невозможно. @ContentChild В компоненте просматривается содержимое внутри тега components. Например: <my-cmp><ng-template #cmp_anchor></ng-template></my-cmp> , вернет шаблон, если вы установите @ContentChild для MyComponent класса.

Нет прямого способа доступа ng-template к компоненту, спроектированному с помощью ngComponentOutlet . Вы даже не можете получить доступ к HelloComponent экземпляру.

Вы можете сделать частный доступ к _componentRef ngComponentOutlet экземпляру, но это немного сложно. Я предлагаю вам вернуться к чертежной доске или перефразировать свой вопрос, указав, какую большую проблему вы пытаетесь решить с помощью своего запроса. В любом случае, чтобы заставить его работать, вы можете (но не должны) выполнить следующее:

 @Component({
  template: `
    <div>Hello Component is here!</div>

    <ng-template #cmp_anchor>
      <div>Template content</div>
    </ng-template>
  `,
})
export class HelloComponent  {
  @ViewChild('cmp_anchor', {read: TemplateRef})
  cmpTemplateRef: TemplateRef<any>;
}

@Component({
  selector: 'my-app',
  template: `
    <ng-container *ngComponentOutlet="helloComponent"></ng-container>

    <ng-container
      [ngTemplateOutlet]="$any(ng)?._componentRef.instance.cmpTemplateRef">
    </ng-container>
  `
})
export class AppComponent  {
  public helloComponent = HelloComponent;

  @ViewChild(NgComponentOutlet) ng: NgComponentOutlet;
}
  

рабочий пример

Если вы все еще считаете, что вам нужно сделать это таким образом, вы всегда можете написать свою собственную структурную директиву на основе ngComponentOutlet директивы. Оттуда вы можете предоставлять всевозможные данные из того, что передается в директиву outlet

Комментарии:

1. Это приводит к ошибке компиляции в angular 9 , где используется ivy

2. @AleksandarPetrovic это своего рода хак, я могу себе представить, что это так. Я добавил a $any() вокруг ng в шаблоне. Это должно исправить эту ошибку. Тем не менее, я не думаю, что вам следует использовать это решение, как я уже говорил ранее