Angolare 2 Mostra e nascondi un elemento


174

Sto riscontrando un problema nel nascondere e mostrare un elemento dipendente da una variabile booleana in Angular 2.

questo è il codice per il div da mostrare e nascondere:

<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 variabile è "modificata" ed è memorizzata nel mio componente:

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'elemento è nascosto, quando si avvia la funzione saveTodos, viene mostrato l'elemento, ma dopo 3 secondi, anche se la variabile torna ad essere falsa, l'elemento non si nasconde. Perché?

Risposte:


167

È necessario utilizzare la direttiva * 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);
  }
}

Aggiornamento: manca il riferimento all'ambito esterno quando ci si trova nel callback di Timeout.

quindi aggiungi .bind (questo) come ho aggiunto sopra

D: modificato è una variabile globale. Quale sarebbe il tuo approccio in un * ngFor-loop? - Blauhirn

A: Aggiungerei modifica come proprietà all'oggetto su cui sto ripetendo.

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

editedè una variabile globale. Quale sarebbe il tuo approccio all'interno di un *ngFor-loop?
phil294,

Modificato non sarebbe una variabile globale, appartiene al componente. Aggiungerò la risposta sopra.
inoabriano il

come accedere al timer a livello globale dal servizio?
Kumaresan Perumal,

1
ngif fa sì che alcuni componenti del materiale angolare non inizializzino e funzionino correttamente, come Mat-paginator. Penso che l'uso di [nascosto] sia la scelta migliore per alcuni casi.
AmirHossein Rezaei,

186

Esistono due opzioni a seconda di ciò che si desidera ottenere:

  1. È possibile utilizzare la direttiva nascosta per mostrare o nascondere un elemento

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
  2. È possibile utilizzare la direttiva di controllo ngIf per aggiungere o rimuovere l'elemento. Questo è diverso dalla direttiva nascosta perché non mostra / nasconde l'elemento, ma aggiunge / rimuove dal DOM. È possibile perdere i dati non salvati dell'elemento. Può essere la scelta migliore per un componente di modifica che viene annullato.

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

Per problemi di modifica dopo 3 secondi, può essere dovuto a incompatibilità con setTimeout. Hai incluso la libreria angular2-polyfills.js nella tua pagina?


5
[hidden]="edited"non sembra avere alcun effetto ...?
phil294,

5
In caso di problemi con nascosto, seguire la risposta di stackoverflow.com/a/35578093/873282 : [hidden] { display: none !important;}nel CSS globale.
koppor,

30

Quando non ti interessa rimuovere l'elemento Dom HTML Html, usa * ngIf.

Altrimenti, usa questo:

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

14

Per mostrare il componente figlio che stavo usando *ngif="selectedState == 1"

Invece di quello che ho usato [hidden]="selectedState!=1"

Ha funzionato per me .. caricare correttamente il componente figlio e dopo aver nascosto e nascosto il componente figlio non è stato definito dopo averlo usato.


6

Questo è un buon caso d'uso per una direttiva. Qualcosa del genere è sorprendentemente 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);
  }
}

Mi piace l'idea, ma questo rimuoverà completamente l'elemento. L'ho cambiato per nasconderlo, quindi potresti riutilizzarlo ma ciò non nasconde l'elemento presumibilmente a causa di ngIfis true. C'è un modo per impostare la variabile del genitore che lo controlla false?
occasionale

Non puoi semplicemente aggiungere una classe nascosta o qualcosa invece di chiamare remove? Questa tecnica è piuttosto generica.
Aluan Haddad,

Penso che il problema sia ngIfmaggiore se l'elemento è nel DOM o meno. Quello che voglio è questo: <div [hidden]="messages" [removeAfter]=3000>...dove mostro / nascondo i messaggi se ce ne sono e quindi rimuovo i messaggi dopo 3 secondi in modo che l'utente non debba chiudere la casella. Ho aggiunto la tua direttiva sopra e l'ho cambiata per fare un hide()ma non viene chiamato quando vengono visualizzati i messaggi. Come ottengo che sia invocato sull'evento? @Output()e EventEmitter?
occasionale

4

Possiamo farlo utilizzando lo snippet di codice seguente.

Codice angolare:

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

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

3

A seconda delle tue esigenze *ngIfo [ngClass]="{hide_element: item.hidden}"dove si hide_elementtrova la classe CSS{ display: none; }

*ngIfpuò causare problemi se si sta modificando la *ngIfrimozione delle variabili di stato , in quei casi display: none;è necessario l' utilizzo di CSS .


0

La soluzione @inoabrian sopra ha funzionato per me. Mi sono imbattuto in una situazione in cui avrei aggiornato la mia pagina e il mio elemento nascosto sarebbe riapparso sulla mia pagina. Ecco cosa ho fatto per risolverlo.

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

ngOnInit() {
      if (condition is true) {
        this.showJoinTodayBtn = true;
      } else {
        this.showJoinTodayBtn = false;
      }
}

0

Basta aggiungere bind (questo) nella funzione setTimeout che inizierà a funzionare

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

e in cambio 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>

Per

<div *ngIf="edited" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.