web-dev-qa-db-fra.com

Comment envelopper conditionnellement une div autour de ng-content

en fonction de la valeur d'une variable de classe (booléenne), je voudrais que mon ng-content pour être enveloppé dans un div ou pour ne pas être enveloppé dans div (c'est-à-dire que le div ne devrait même pas être dans le DOM) ... Quelle est la meilleure façon de procéder? J'ai un Plunker qui essaie de faire cela, de ce que j'ai supposé être le moyen le plus évident, en utilisant ngIf .. mais cela ne fonctionne pas ... Il affiche le contenu uniquement pour l'une des valeurs booléennes mais pas L'autre

veuillez aider Merci!

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 {}
32
Somo S.

Angulaire ^ 4

Comme solution de contournement, je peux vous proposer la solution suivante:

<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>

Exemple Plunker angular v4

Angulaire <4

Ici, vous pouvez créer une directive dédiée qui fera les mêmes choses:

<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>

Exemple Plunker

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

N'oubliez pas que vous pouvez mettre toute cette logique dans un composant séparé! (basé sur la réponse yurzui):

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

Vous pouvez ensuite l'utiliser comme ceci:

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

J'ai vérifié cela et trouvé un problème ouvert sur le sujet des transclusions multiples avec la balise. Cela vous empêche de définir plusieurs balises dans un seul fichier de modèle.

Cela explique pourquoi le contenu ne s'affiche correctement que lorsque l'autre balise est supprimée dans votre exemple de plunker.

Vous pouvez voir le problème ouvert ici: https://github.com/angular/angular/issues/7795

2
Jolmari