简体   繁体   English

Angular 2 以编程方式绑定 ngIf

[英]Angular 2 binding ngIf programmatically

I am building a page header component which has two states:我正在构建一个页面标题组件,它有两种状态:

  • Standard: Shows detailed content标准:显示详细内容
  • Compacted: Shows minimal content压缩:显示最少的内容

The idea is that this component can be added to any 'page' component like so:这个想法是这个组件可以添加到任何“页面”组件,如下所示:

home.component.html主页.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>

The code I have so far:我到目前为止的代码:

page-header.component.html页面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>

page-header.component.ts page-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;
    }
}

The Question: How do I assign an ngIf to the two ContentChild components in the ngOnInit function?问题:如何将 ngIf 分配给 ngOnInit 函数中的两个 ContentChild 组件? ie show one component when the compacted input is true and then show the other when the compacted input is false即在compacted输入为真时显示一个组件,然后在compacted输入为假时显示另一个组件

You can't dynamically add ngIf .您不能动态添加ngIf You can set the hidden attribute可以设置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);
}

If the header will only have standard/compact components you could project them like this and use *ngIf directly in that template如果标题只有标准/紧凑组件,您可以像这样投影它们并直接在该模板中使用*ngIf

For page-header.component.html对于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>

This was resolved in the end by using a template loader directive.最后通过使用模板加载器指令解决了这个问题。

The template loader directive allows the user to optionally include either the header compact and header standard templates.模板加载器指令允许用户选择性地包含头文件压缩模板和头文件标准模板。 If either template is not included it is hidden and no empty divs or containers are left in the markup.如果其中一个模板未包含在内,则它会被隐藏,并且标记中不会留下任何空的 div 或容器。

The resulting (simplified) markup looks like:生成的(简化的)标记如下所示:

app.component.html应用程序组件.html

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

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

page-header.component.html页面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>

page-header.component.ts page-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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM