Angular 2 Afficher et masquer un élément

174

J'ai un problème à cacher et à afficher un élément dépendant d'une variable booléenne dans Angular 2.

voici le code que le div doit afficher et masquer:

<div *ngIf="edited==true" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>

la variable est "éditée" et elle est stockée dans mon composant:

export class AppComponent implements OnInit{

  (...)
  public edited = false;
  (...)
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }, 3000);
  }
}

L'élément est masqué, lorsque la fonction saveTodos démarre, l'élément est affiché, mais après 3 secondes, même si la variable revient à false, l'élément ne se cache pas. Pourquoi?


la source

Réponses:

167

Vous devez utiliser la directive * ngIf

<div *ngIf="edited" class="alert alert-success box-msg" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>


export class AppComponent implements OnInit{

  (...)
  public edited = false;
  (...)
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);
  }
}

Mise à jour: il vous manque la référence à la portée externe lorsque vous êtes dans le rappel Timeout.

alors ajoutez le .bind (ceci) comme j'ai ajouté ci-dessus

Q: édité est une variable globale. Quelle serait votre approche dans une boucle * ngFor? - Blauhirn

R: J'ajouterais edit en tant que propriété à l'objet sur lequel j'itère.

<div *ngFor="let obj of listOfObjects" *ngIf="obj.edited" class="alert alert-success box-msg" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>


export class AppComponent implements OnInit{
   
  public listOfObjects = [
    {
       name : 'obj - 1',
       edit : false
    },
    {
       name : 'obj - 2',
       edit : false
    },
    {
       name : 'obj - 2',
       edit : false
    } 
  ];
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);
  }
}
inoabrien
la source
editedest une variable globale. Quelle serait votre approche dans un *ngFor-loop?
phil294
Edité ne serait pas une variable globale, il appartient au composant. J'ajouterai la réponse ci-dessus.
inoabrian
comment accéder à la minuterie globalement depuis le service?
Kumaresan Perumal
1
ngif provoque l'échec de l'initialisation et du bon fonctionnement de certains composants angulaires, comme mat-paginator. Je pense que l'utilisation de [hidden] est un meilleur choix dans certains cas.
AmirHossein Rezaei
186

Il existe deux options en fonction de ce que vous souhaitez réaliser:

  1. Vous pouvez utiliser la directive hidden pour afficher ou masquer un élément

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
    
  2. Vous pouvez utiliser la directive de contrôle ngIf pour ajouter ou supprimer l'élément. Ceci est différent de la directive masquée car elle n'affiche / masque pas l'élément, mais elle ajoute / supprime du DOM. Vous pouvez perdre les données non enregistrées de l'élément. Cela peut être le meilleur choix pour un composant d'édition qui est annulé.

    <div *ngIf="edited" class="alert alert-success box-msg" role="alert"> 
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
    

Pour votre problème de changement au bout de 3 secondes, cela peut être dû à une incompatibilité avec setTimeout. Avez-vous inclus la bibliothèque angular2-polyfills.js dans votre page?

gentiane
la source
5
[hidden]="edited"ne semble pas avoir d'effets ...?
phil294
5
Si vous rencontrez des problèmes avec hidden, veuillez suivre la réponse de stackoverflow.com/a/35578093/873282 : [hidden] { display: none !important;}dans votre css global.
koppor le
30

Lorsque vous ne vous souciez pas de supprimer l'élément Html Dom-Element, utilisez * ngIf.

Sinon, utilisez ceci:

<div [style.visibility]="(numberOfUnreadAlerts == 0) ? 'hidden' : 'visible' ">
   COUNTER: {{numberOfUnreadAlerts}} 
</div>
Dudi
la source
14

Pour que le composant enfant montre que j'utilisais *ngif="selectedState == 1"

Au lieu de cela, j'ai utilisé [hidden]="selectedState!=1"

Cela a fonctionné pour moi .. le chargement du composant enfant correctement et après cacher et un-hide composant enfant n'était pas indéfini après avoir utilisé cela.

Swapnil Kale
la source
6

C'est un bon cas d'utilisation pour une directive. Quelque chose comme ça est étonnamment utile.

@Directive({selector: '[removeAfter]'}) export class RemoveAfter {
  constructor(readonly element: ElementRef<HTMLElement>) { }

  /**
   * Removes the attributed element after the specified number of milliseconds. 
   * Defaults to (1000)
   */
  @Input() removeAfter = 1000;


  ngOnInit() {
    setTimeout(() => {
      this.element.nativeElement.remove();
    }, this.removeAfter);
  }
}
Aluan Haddad
la source
J'aime l'idée, mais cela supprimera complètement l'élément. Je l'ai changé pour le cacher, vous pouvez donc le réutiliser, mais cela ne cache pas l'élément probablement en raison de l' ngIfest true. Existe-t-il un moyen de définir la variable du parent qui contrôle cela sur false?
occasionnel
Ne pouvez-vous pas simplement ajouter une classe cachée ou quelque chose au lieu d'appeler remove? Cette technique est assez générique.
Aluan Haddad
Je pense que le problème est ngIfplus de savoir si l'élément est dans le DOM ou non. Ce que je veux, c'est ceci: <div [hidden]="messages" [removeAfter]=3000>...où je montre / masque les messages s'il y en a, puis supprime les messages après 3 secondes pour que l'utilisateur n'ait pas à fermer la boîte. J'ai ajouté votre directive ci-dessus et l'ai commutée pour faire un hide()mais elle n'est pas appelée lorsque les messages sont affichés. Comment puis-je l'invoquer lors de l'événement? @Output()et EventEmitter?
occasl
4

Nous pouvons le faire en utilisant l'extrait de code ci-dessous.

Code angulaire:

 export class AppComponent {  
    toggleShowHide: string = "visible";  
 }

Modèle HTML:

  Enter text to hide or show item in bellow: 
  <input type="text" [(ngModel)]="toggleShowHide">
  <br>
  Toggle Show/hide:
  <div [style.visibility]="toggleShowHide">   
     Final Release Angular 2!
  </div>
Rejwanul Reja
la source
3

En fonction de vos besoins, *ngIfou [ngClass]="{hide_element: item.hidden}"lorsque la classe CSS hide_elementest{ display: none; }

*ngIfpeut causer des problèmes si vous changez les variables d'état *ngIfest la suppression, dans ces cas, l'utilisation de CSS display: none;est requise.

Luke Dupin
la source
0

La solution @inoabrian ci-dessus a fonctionné pour moi. Je suis tombé sur une situation où je rafraîchirais ma page et mon élément caché réapparaîtrait sur ma page. Voici ce que j'ai fait pour le résoudre.

export class FooterComponent implements OnInit {
public showJoinTodayBtn: boolean = null;

ngOnInit() {
      if (condition is true) {
        this.showJoinTodayBtn = true;
      } else {
        this.showJoinTodayBtn = false;
      }
}
Jason Spence
la source
0

Ajoutez simplement bind (this) dans votre fonction setTimeout, cela commencera à fonctionner

setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);

et en changement HTML

<div *ngIf="edited==true" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>

À

<div *ngIf="edited" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>
Mukesh Rawat
la source