44 votes

Comment envelopper conditionnellement une div autour du ng-content

En fonction de la valeur d'une variable de classe (booléenne), je voudrais que mon ng-content soit soit enveloppé dans un div, soit ne soit pas enveloppé dans un 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 le faire, de la manière la plus évidente que j'ai supposée, en utilisant ngIf .. mais cela ne fonctionne pas... Il affiche du contenu uniquement pour une des valeurs booléennes mais pas pour l'autre

veuillez aider Merci !

http://plnkr.co/edit/omqLK0mKUIzqkkR3lQh8

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

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

@Component({
  template: `
     ... "Voici le contenu"  ... 
  `
})
export class App {}

0 votes

Bon plunkr, bonne question.. J'ai bidouillé avec ça et je n'arrive pas à le comprendre non plus. Je serais intéressé de connaître la solution

82voto

yurzui Points 85802

Angular ^4

En guise de solution temporaire, je peux vous proposer la solution suivante :

Exemple Plunker angular v4

Angular < 4

Ici, vous pouvez créer une directive dédiée qui fera la même chose :

Exemple Plunker

ngIf4.ts

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

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

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

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

  @Input()
  set ngIf4Else(templateRef: TemplateRef) {
    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);
      }
    }
  }
}

5 votes

J'aimerais pouvoir voter pour cela deux fois. J'ai passé une éternité à essayer de comprendre comment utiliser ng-content à l'intérieur de *ngIf

0 votes

Merci Yurzi, cet exemple ci-dessus était ce que j'ai passé beaucoup de temps à essayer de formuler pour une recherche sur Google. Angular 5 fonctionne bien avec cela.

0 votes

Fonctionne très bien! Plutôt impressionnant d'ailleurs. Je viens de me lancer dans Angular, mais je suis constamment impressionné par sa puissance.

8voto

charlie_pl Points 834

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

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

@Component({
    selector: 'div-wrapper',
    template: `

    `,
})
export class ConditionalDivComponent {
  @Input()
  public wrap = false;
}

Vous pouvez ensuite l'utiliser comme ceci:

 Bonjour tout le monde!

2 votes

J'aime mieux cette réponse. Les autres réponses ont une complexité html trop importante

2voto

Jolmari Points 31

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

Cela explique pourquoi le contenu est affiché correctement uniquement lorsque l'autre balise ng-template est supprimée dans votre exemple plunker.

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

0 votes

Je suppose que puisque les ngIf sont mutuellement exclusifs, les deux "ng-contents" ne sont jamais affichés en même temps, donc ils ne vont pas "entrer en conflit"... L'autre chose étrange est que cela ne provoque ni d'échec brutal ni d'avertissement, il n'y a aucune erreur de quelque nature que ce soit, pourtant cela ne fonctionne clairement pas comme on pourrait le penser.. Merci pour le problème, je vais le suivre de près!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X