Angular 角度2-包裹组件子级

Angular 角度2-包裹组件子级,angular,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&

我试图创建一个可重用的选项卡组件,但对于如何在组件中迭代多个
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>

首先,这些链接不是Tabs组件的@ViewChildren(),而是@ContentChildren(),因为@ViewChildren()必须在组件的模板中声明,而@ContentChildren()来自外部声明-就像您所做的那样

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

link.directive.ts

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

@Directive({
    selector: '[appLink]'
})
export class AppLinkDirective {
    constructor(public template: TemplateRef<any>) { }
}
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() {
    }

}
从'@angular/core'导入{指令,TemplateRef};
@指示({
选择器:“[appLink]”
})
导出类AppLinkDirective{
构造函数(公共模板:TemplateRef){}
}
这是一个结构指令,可以接收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>

表1
表2
表3
最后,在组件的模板中渲染它们:

选项卡.组件.ts

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

@Directive({
    selector: '[appLink]'
})
export class AppLinkDirective {
    constructor(public template: TemplateRef<any>) { }
}
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() {
    }

}
从'@angular/core'导入{Component,ContentChildren,OnInit,QueryList};
从“./link.directive”导入{AppLinkDirective};
@组成部分({
选择器:“应用程序演示选项卡”,
模板:`
` }) 导出类TabsComponent实现OnInit{ @ContentChildren(AppLinkDirective) 链接:QueryList; 构造函数(){ } 恩戈尼尼特(){ } }

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

一些替代解决方案,但我喜欢您的answer@yurzui,是的,这当然是可能的,而且一点也不坏,但我实际上喜欢在html中放尽可能少的东西——这样它读起来更清晰,重要的东西也不那么隐藏在成堆的次要html东西下面。这非常有效。我也看到了@yurzui的解决方案,我也看到了它的工作原理,但我同意,这一点更清楚(对像我这样的noob来说)。谢谢