Angular 2 - Wrap组件子

时间:2017-10-10 17:53:20

标签: angular

我试图制作一个可重复使用的标签组件,并对如何在组件中迭代多个ContentChildren(已更正)以将其包装在html中感到困惑。

我的观点中有一个组件

<demo-tabs>
  <a routerLink="/some/link">Tab 1</a>
  <a routerLink="/some/other/link">Tab 2</a>
  <a routerLink="/some/third/link">Tab 3</a>
</demo-tabs>

我想像这样呈现:

<ul>
  <li><a routerLink="/some/link">Tab 1</a></li>
  <li><a routerLink="/some/other/link">Tab 2</a></li>
  <li><a routerLink="/some/third/link">Tab 3</a></li>
<ul>

我似乎无法在ng-content中嵌入内容,这是我首先尝试的内容,以下模板以ExpressionChangedAfterItHasBeenCheckedError

爆炸
@Component({
  selector: 'demo-tabs',
  template: `<ul class="tabs">
    <li *ngFor="let a of links">
      {{a}}
    </li>
  </ul>`})
export class TabsComponent implements OnInit {
  @ContentChildren('a') links: TemplateRef<any>; // corrected. I originally had this as @ViewChildren

  constructor() { }

  ngOnInit() {
  }

}

1 个答案:

答案 0 :(得分:3)

首先,这些链接不是Tabs组件的@ViewChildren() - 它们是@ContentChildren(),因为@ViewChildren()必须在组件的模板中声明,而@ContentChildren()即将到来来自外部声明 - 就像你一样。

为了能够以这种方式分离内容,您需要标记&#34;所有具有非常简单的自定义结构指令的元素(如下所示),以便您可以将它们作为TabsComponent中单独项目的列表。

<强> link.directive.ts

import {Directive, TemplateRef} from '@angular/core';

@Directive({
    selector: '[appLink]'
})
export class AppLinkDirective {
    constructor(public template: TemplateRef<any>) { }
}

这是一个结构指令,可以接收HTML模板作为DI注入令牌。这个项目的模板是我们实际需要渲染到TabsComponent模板中的。

然后,让我们标记我们的项目:

<强> app.component.html

<app-demo-tabs>
    <a *appLink routerLink="/some/link">Tab 1</a>
    <a *appLink routerLink="/some/other/link">Tab 2</a>
    <a *appLink routerLink="/some/third/link">Tab 3</a>
</app-demo-tabs>

最后,在组件的模板中渲染它们:

<强> tabs.component.ts

import {Component, ContentChildren, OnInit, QueryList} from '@angular/core';
import {AppLinkDirective} from './link.directive';

@Component({
    selector: 'app-demo-tabs',
    template: `
        <ul class="tabs">
            <li *ngFor="let link of links">
                <ng-template [ngTemplateOutlet]="link?.template"></ng-template>
            </li>
        </ul>`
})
export class TabsComponent implements OnInit {

    @ContentChildren(AppLinkDirective)
    links: QueryList<AppLinkDirective>;

    constructor() {
    }

    ngOnInit() {
    }

}

当然,您需要在某个模块中导入此指令,以便可以在模板中使用它。