【问题标题】:Displaying content of Component that i fetched with @ContentChildren or @ViewChild显示我使用 @ContentChildren 或 @ViewChild 获取的组件的内容
【发布时间】:2020-11-06 10:11:50
【问题描述】:

所以我试图在我的组件中的特定位置显示子组件。

我有以下几点:

@Component({
  selector: 'app-item-list',
  template: `
<p *ngFor="let item of items">
  {{item.order}}
  <!-- display content of child component here -->
</p>`
})
export class ItemListComponent implements OnInit, AfterContentInit {

  //Get all child components of the type ItemComponent and store them.
  @ContentChildren(ItemComponent, {descendants: true}) 
  items?: QueryList<ItemComponent>;
  constructor() { }

  ngOnInit() {
  }
    
  ngAfterContentInit(): void {
      
  }

}

@Component({
  selector: 'app-item',
  template: `
<p>
  item works!
</p>
<ng-content></ng-content>
`
})
export class ItemComponent implements OnInit {

  @Input() order?: string;
  constructor() { }

  ngOnInit() {
  }

}

我尝试使用 &lt;ng-content select="item"&gt; 显示它,但没有成功。

以下内容:

<app-item-list>
  <app-item order="2">
    test2
  </app-item>
  <app-item order="1">
    test1
  </app-item>
</app-item-list>

预期的输出是

2
item works!
test2
1
item works!
test1

https://stackblitz.com/edit/angular-ivy-2aibgt

【问题讨论】:

    标签: javascript angular typescript angular10


    【解决方案1】:

    看看this。之前我以为没有办法实现你的输出,但我终于想通了。

    我所做的是消除 @ContentChildren 方法,而是用从 app 组件传递的 items Input 替换它。我遍历项目,显示订单和对应的app-item 组件。

    【讨论】:

    • 请在你的回答中解释你做了什么。它将帮助提问者和社区。​​span>
    • 遗憾的是,在我想使用角度标记来定义内容之后,这不是一个与我想要的解决方案相匹配的解决方案。
    【解决方案2】:

    我可以建议您在 Angular 材料库中使用的解决方案。

    • app-item组件的内容包裹在&lt;ng-template&gt;标签中

    item.component.html

    <ng-template>  <----------------------------- wrapper
      <p>
        item works!
      </p>
      <ng-content></ng-content>
    </ng-template>
    
    • 然后我们可以获取对 TemplateRef 的引用

    item.component.ts

    @ViewChild(TemplateRef, {static: true}) template: TemplateRef<any>;
    
    • 我们终于可以在app-item-list组件的循环中使用它了

    item-list.component.html

    <p *ngFor="let item of items">
      {{item.order}}
      <ng-template [ngTemplateOutlet]="item.template"></ng-template>
    </p>
    

    Forked Stackblitz

    【讨论】:

    • 感谢这满足了我的需要!
    【解决方案3】:

    真的没有办法使用ng-content(据我所知)来实现这一点。 ng-content 仅用于静态内容投影。

    看看这里的用例 - https://github.com/angular/angular/issues/8563 - 第 2 段证实了您必须使用带有 viewref 的查询来做您想做的事情,即@yurzui 提供的解决方案。

    您始终可以使用选择器静态选择要投影的内容的哪一部分,但我怀疑这不是您要查找的内容:

    <ng-content select="[order=2]">
    </ng-content>
    <ng-content select="[order=1]">
    </ng-content>
    

    【讨论】:

      【解决方案4】:

      您可能错过了在item-list.component.html 中添加select 项目引用变量

      item.component.html

      <p>item works</p>
      <ng-content select="[body]">
      </ng-content>
      

      item-list.component.html

      <p *ngFor="let item of items">
        <app-item >
        <div body>
            {{item.order}}
        </div>
        </app-item>
        test2
      </p>
      

      参考:Stackblitz example

      【讨论】:

        猜你喜欢
        • 2016-11-02
        • 2017-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多