在 Angular 的 ContentChildren 中渲染组件

use*_*782 13 components typescript angular

这是我的组件:

import { Component, OnInit, ContentChildren, QueryList } from '@angular/core';
import { IconBoxComponent } from '../icon-box/icon-box.component';

@Component({
  selector: 'app-three-icon-box',
  templateUrl: './three-icon-box.component.html',
  styleUrls: ['./three-icon-box.component.scss']
})
export class ThreeIconBoxComponent implements OnInit {
  @ContentChildren(IconBoxComponent) boxes: QueryList<IconBoxComponent>;

  constructor() { }

  ngOnInit() {
  }

  ngAfterContentInit() {
    console.log(this.boxes);
  }

}
Run Code Online (Sandbox Code Playgroud)

它的模板如下所示:

<div class="row justify-content-center">
  <div class="col-12 col-md-10">
    <div class="row justify-content-center text-center">
      <div *ngFor="let box of boxes" class="col-12 col-sm-4 col-lg-3 offset-lg-1 lz-mb-2 lz-mb-sm-0">
        {{ box }}
      </div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

这就是我渲染它的方式:

  <app-three-icon-box>
    <app-icon-box icon="#icon-one">content 1</app-icon-box>
    <app-icon-box icon="#icon-two">content 2</app-icon-box>
    <app-icon-box icon="#icon-three">content 3</app-icon-box>
  </app-three-icon-box>
Run Code Online (Sandbox Code Playgroud)

在第二个代码块中,我试图呈现<app-icon-box>,但我不知道如何呈现。 {{ box }}只是我正在尝试做的事情的一个想法,但我只是得到[object Object].

Ili*_*olk 15

你应该使用这种模式

  1. 创建 TemplateMarker 指令以标记要作为参数传递的模板(以防止抓取其他模板)。
  2. 使用 注入标记@ContentChildren
  3. 使用NgTemplateOutlet在需要的地方渲染它们。

提示:您可以多次渲染每个模板并向它们发送参数

例子:

import { Component, Input, Directive, TemplateRef, ContentChildren, QueryList } from '@angular/core';
@Directive({
  selector: '[templateMarker]'
})
export class TemplateMarker {
  constructor(public template: TemplateRef<any>) {}
}
@Component({
  selector: 'template-owner',
  template: `
    <div *ngFor="let marker of markers">
      <i><ng-template [ngTemplateOutlet]="marker.template"></ng-template></i>
    </div>
  `,
})
export class TemplateOwner {
  @ContentChildren(TemplateMarker) markers: QueryList<TemplateMarker>;
}
@Component({
  selector: 'hello',
  template: `<template-owner>
    <div *templateMarker>first template</div>
    <div *templateMarker>second template</div>
  </template-owner>`,
})
export class HelloComponent  {}
Run Code Online (Sandbox Code Playgroud)


Dav*_*Ibl 7

有点不清楚你需要什么。但我想使用 ng-content 就足够了。删除 ContentChildren 和 ngFor 并使用

<ng-content></ng-content>
Run Code Online (Sandbox Code Playgroud)

在您的模板中。

然后你必须直接在你的盒子组件被声明的地方添加类。

<app-icon-box class="col-12 col-sm-4 col-lg-3 offset-lg-1 lz-mb-2 lz-mb-sm-0" icon="#here-to-help-you">
Run Code Online (Sandbox Code Playgroud)

要丰富 ThreeIconBoxComponent 中的投影组件,您将需要使用模板和模板出口的完全不同的方法。