How to conditionally wrap a div around ng-content

99封情书 提交于 2019-11-27 18:45:13

Angular ^4

As workaround i can offer you the following solution:

<div *ngIf="insideRedDiv; else elseTpl" style="display: inline; border: 1px red solid">
  <ng-container *ngTemplateOutlet="elseTpl"></ng-container>
</div>

<ng-template #elseTpl><ng-content></ng-content> </ng-template>

Plunker Example angular v4

Angular < 4

Here you can create dedicated directive that will do the same things:

<div *ngIf4="insideRedDiv; else elseTpl" style="display: inline; border: 1px red solid">
   <ng-container *ngTemplateOutlet="elseTpl"></ng-container>
</div>

<template #elseTpl><ng-content></ng-content></template>

Plunker Example

ngIf4.ts

class NgIfContext { public $implicit: any = null; }

@Directive({ selector: '[ngIf4]' })
export class NgIf4 {
  private context: NgIfContext = new NgIfContext();
  private elseTemplateRef: TemplateRef<NgIfContext>;
  private elseViewRef: EmbeddedViewRef<NgIfContext>;
  private viewRef: EmbeddedViewRef<NgIfContext>;

  constructor(private viewContainer: ViewContainerRef, private templateRef: TemplateRef<NgIfContext>) { }

  @Input()
  set ngIf4(condition: any) {
    this.context.$implicit = condition;
    this._updateView();
  }

  @Input()
  set ngIf4Else(templateRef: TemplateRef<NgIfContext>) {
    this.elseTemplateRef = templateRef;
    this.elseViewRef = null;
    this._updateView();
  }

  private _updateView() {
    if (this.context.$implicit) {
      this.viewContainer.clear();
      this.elseViewRef = null;

      if (this.templateRef) {
        this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this.context);
      }
    } else {
      if (this.elseViewRef) return;

      this.viewContainer.clear();
      this.viewRef = null;

      if (this.elseTemplateRef) {
        this.elseViewRef = this.viewContainer.createEmbeddedView(this.elseTemplateRef, this.context);
      }
    }
  }
}

Remember that you can put all this logic in separate component! (based on yurzui answer):

import { Component, Input } from '@angular/core';

@Component({
    selector: 'div-wrapper',
    template: `
    <div *ngIf="wrap; else unwrapped">
      <ng-content *ngTemplateOutlet="unwrapped">
      </ng-content>
    </div>
    <ng-template #unwrapped>
      <ng-content>
      </ng-content>
    </ng-template>
    `,
})
export class ConditionalDivComponent {
  @Input()
  public wrap = false;
}

You can then use it like this:

<div-wrapper [wrap]="'true'">
 Hello world!        
</div-wrapper>

I checked into this and found an open issue on the subject of multiple transclusions with the tag. This prevents you from defining multiple tags in a single template file.

This explains why the content is displayed correctly only when the other tag is removed in your plunker example.

You can see the open issue here: https://github.com/angular/angular/issues/7795

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!