Angular 2绑定ngIf以编程方式

时间:2017-01-18 05:54:50

标签: javascript angular

我正在构建一个页眉组件,它有两种状态:

  • 标准:显示详细内容
  • 压缩:显示最少内容

我们的想法是,这个组件可以添加到任何页面'像这样的组件:

home.component.html

<app-page-header>

    <app-page-header-standard>
        // Standard Content
    </app-page-header-standard>

    <app-page-header-compact>
        // Compact Content
    </app-page-header-compact>

</app-page-header>

到目前为止我的代码:

页-header.component.html

<div class="wrapper">

    <!-- The standard and compact components are transcluded here -->
    <ng-content></ng-content>

    <a (click)="toggleHeaderState()">Toggle me</a>
</div>

页-header.component.ts

import {Component, OnInit, ViewEncapsulation, Input, ContentChild} from '@angular/core';
import {PageHeaderStandardComponent} from "./page-header-standard.component";
import {PageHeaderCompactComponent} from "./page-header-compact.component";

@Component({
    selector: 'app-page-header',
    templateUrl: './page-header.component.html',
    styleUrls: ['./page-header.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class PageHeaderComponent implements OnInit {

    @ContentChild(PageHeaderStandardComponent) headerStandard: PageHeaderStandardComponent;
    @ContentChild(PageHeaderCompactComponent) headerCompact: PageHeaderCompactComponent;

    /**
     * Toggle the header standard and compact state
     * @type {boolean}
     */
    @Input() compacted: boolean = false;

    constructor() {
    }

    ngOnInit() {
        console.log(this.headerStandard);
        console.log(this.headerCompact);

        // TODO
        // Bind compact and standard component to compacted input
        // i.e. one hides while the other shows
    }

    toggleHeaderState() {
        this.compacted = !this.compacted;
    }
}

问题: 如何为ngOnInit函数中的两个ContentChild组件分配ngIf?即在compacted输入为真时显示一个组件,然后在compacted输入为假时显示另一个组件

3 个答案:

答案 0 :(得分:1)

您无法动态添加ngIf。您可以设置hidden属性

@ContentChild(PageHeaderStandardComponent, {read: ElementRef}) headerStandard: PageHeaderStandardComponent;
@ContentChild(PageHeaderCompactComponent, {read: ElementRef}) headerCompact: PageHeaderCompactComponent;

ngAfterViewInit() {
    console.log(this.headerStandard);
    console.log(this.headerCompact);
    this.headerStandard.nativeElement.setAttribute('hidden', !compacted);
    this.headerCompact.nativeElement.setAttribute('hidden', compacted);
}

答案 1 :(得分:1)

如果标题只有标准/紧凑组件,您可以像这样投影它们并直接在该模板中使用*ngIf

page-header.component.html

<div class="wrapper">
    <ng-content select="app-page-header-standard" *ngIf="!compacted"></ng-content>

    <ng-content select="app-page-header-compact" *ngIf="compacted"></ng-content>

    <a (click)="toggleHeaderState()">Toggle me</a>
</div>

答案 2 :(得分:0)

最后通过使用模板加载器指令解决了这个问题。

模板加载器指令允许用户可选地包括标题紧凑和标题标准模板。如果没有包含任何一个模板,它将被隐藏,并且标记中不会留下空的div或容器。

生成的(简化)标记如下所示:

<强> app.component.html

<wbo-page-header>
    <template pageHeaderStandardTemplate>
        // Standard Content
    </template>

    <template pageHeaderCompactTemplate>
        // Compact Content
    </template>
</wbo-page-header>

页-header.component.html

<div class="wrapper">

    <div class="header-standard" *ngIf="pageHeaderStandardTemplate && !compacted" >
        <template [templateLoader]="pageHeaderStandardTemplate"></template>
    </div>

    <div class="header-compact" *ngIf="pageHeaderCompactTemplate && compacted">
        <template [templateLoader]="pageHeaderCompactTemplate"></template>
    </div>

    <span ngIf*="pageHeaderStandardTemplate && pageHeaderCompactTemplate" (click)="toggleCompactedState">Toggle Header</span>
</div>

页-header.component.ts

/**
 * Directive to define a template for the page header standard
 */
@Directive({selector: '[pageHeaderStandardTemplate]'})
export class PageHeaderStandardTemplate {
}

/**
 * Directive to define a template for the page header compact
 */
@Directive({selector: '[pageHeaderCompactTemplate]'})
export class PageHeaderCompactTemplate {
}


@Component({
    // Removed for simplicity
})
export class PageHeaderComponent implements OnInit {

    @Input() compacted: boolean = false;

    /**
     * Define the Page Header Standard template
     */
    @ContentChild(PageHeaderStandardTemplate, {read: TemplateRef}) public pageHeaderStandardTemplate;

    /**
     * Define the Page Header Standard template
     */
    @ContentChild(PageHeaderCompactTemplate, {read: TemplateRef}) public pageHeaderCompactTemplate;

    /**
     * Toggle the header compacted state
     */
    toggleCompactedState() {
        this.compacted = !this.compacted;
    }
}