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

Компонент с 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=1&file=src/app/app.component.ts


person Aleksandar Petrovic    schedule 22.09.2020    source источник


Ответы (1)


Это действительно невозможно. @ContentChild в компоненте просматривает содержимое внутри тега компонентов. Например: <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. Оттуда вы можете раскрыть все виды вещей из того, что передано в директиву выхода

person Poul Kruijt    schedule 22.09.2020
comment
Это вызывает ошибку компиляции в angular 9+, где используется ivy - person Aleksandar Petrovic; 22.09.2020
comment
@AleksandarPetrovic, это своего рода взлом, я могу представить, что это так. Я добавил $any() вокруг ng в шаблоне. Это должно исправить эту ошибку. Тем не менее, я не думаю, что вам следует использовать это решение, как я сказал ранее. - person Poul Kruijt; 22.09.2020