How to conditionally wrap a div around ng-content

吃可爱长大的小学妹 提交于 2019-12-17 10:33:50

问题


depending on the value of a (boolean) class variable I would like my ng-content to either be wrapped in a div or to not be wrapped in div (I.e. the div should not even be in the DOM) ... Whats the best way to go about this ? I have a Plunker that tries to do this, in what I assumed was the most obvious way, using ngIf .. but it's not working... It displays content only for one of the boolean values but not the other

kindly assist Thank you!

http://plnkr.co/edit/omqLK0mKUIzqkkR3lQh8

@Component({
  selector: 'my-component',
  template: `

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

   <ng-content *ngIf="!insideRedDiv"></ng-content>     

  `,
})
export class MyComponent {
  insideRedDiv: boolean = true;
}


@Component({
  template: `
    <my-component> ... "Here is the Content"  ... </my-component>
  `
})
export class App {}

回答1:


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);
      }
    }
  }
}



回答2:


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>



回答3:


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



来源:https://stackoverflow.com/questions/41593973/how-to-conditionally-wrap-a-div-around-ng-content

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