Angular 2 Mostrar y Ocultar un elemento

174

Tengo un problema para ocultar y mostrar un elemento que depende de una variable booleana en Angular 2.

Este es el código para que el div muestre y oculte:

<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á "editada" y se almacena en mi 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);
  }
}

El elemento está oculto, cuando se inicia la función saveTodos, se muestra el elemento, pero después de 3 segundos, incluso si la variable vuelve a ser falsa, el elemento no se oculta. ¿Por qué?


fuente

Respuestas:

167

Debe usar la Directiva * 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);
  }
}

Actualización: falta la referencia al ámbito externo cuando está dentro de la devolución de llamada de tiempo de espera.

así que agregue el .bind (esto) como agregué arriba

P: editado es una variable global. ¿Cuál sería su enfoque dentro de un * ngFor-loop? - Blauhirn

R: Agregaría editar como una propiedad al objeto sobre el que estoy iterando.

<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);
  }
}
inoabrian
fuente
editedEs una variable global. ¿Cuál sería su enfoque dentro de un *ngFor-loop?
phil294
Editado no sería una variable global, pertenece al componente. Agregaré la respuesta anterior.
inoabrian
¿Cómo acceder al temporizador globalmente desde el servicio?
Kumaresan Perumal
1
ngif causa que algunos componentes de material angular no se inicialicen y funcionen correctamente, como mat-paginator. Creo que usar [hidden] es la mejor opción para algunos casos.
AmirHossein Rezaei
186

Hay dos opciones dependiendo de lo que quieras lograr:

  1. Puede usar la directiva oculta para mostrar u ocultar un elemento

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
  2. Puede usar la directiva de control ngIf para agregar o eliminar el elemento. Esto es diferente de la directiva oculta porque no muestra / oculta el elemento, pero agrega / elimina del DOM. Puede perder datos no guardados del elemento. Puede ser la mejor opción para un componente de edición que se cancela.

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

Para su problema de cambio después de 3 segundos, puede deberse a una incompatibilidad con setTimeout. ¿Incluyó la biblioteca angular2-polyfills.js en su página?

gentiane
fuente
55
[hidden]="edited"no parece tener ningún efecto ...?
phil294
55
En caso de que tenga problemas con oculto, siga la respuesta de stackoverflow.com/a/35578093/873282 : [hidden] { display: none !important;}en su CSS global.
koppor
30

Cuando no le importa eliminar el elemento Dom HTML, use * ngIf.

De lo contrario, use esto:

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

Para que el componente secundario muestre que estaba usando *ngif="selectedState == 1"

En lugar de eso usé [hidden]="selectedState!=1"

Funcionó para mí ... cargar el componente hijo correctamente y después de ocultar y no ocultar el componente hijo no estaba indefinido después de usar esto.

Kale Swapnil
fuente
6

Este es un buen caso de uso para una directiva. Algo como esto es sorprendentemente útil.

@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
fuente
Me gusta la idea, pero esto eliminará el elemento por completo. Lo cambié para ocultarlo, por lo que podría reutilizarlo, pero eso no oculta el elemento presumiblemente debido a ngIfis true. ¿Hay alguna manera de establecer la variable del padre que controla esto false?
occasl
¿No puedes simplemente agregar una clase oculta o algo en lugar de llamar a remove? Esta técnica es bastante genérica.
Aluan Haddad
Creo que el problema es ngIfmás si el elemento está en el DOM o no. Lo que quiero es esto: <div [hidden]="messages" [removeAfter]=3000>...donde muestro / oculto mensajes si hay alguno y luego elimino los mensajes después de 3 segundos para que el usuario no tenga que cerrar el cuadro. Agregué su directiva arriba y la cambié para hacer una hide()pero no se llama cuando se muestran los mensajes. ¿Cómo consigo que se invoque en el evento? @Output()y EventEmitter?
occasl
4

Podemos hacerlo usando el siguiente fragmento de código.

Código angular:

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

Plantilla 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
fuente
3

Dependiendo de sus necesidades, *ngIfo [ngClass]="{hide_element: item.hidden}"donde hide_elementes la clase CSS{ display: none; }

*ngIfpuede causar problemas si está cambiando la *ngIfeliminación de variables de estado , en esos casos display: none;se requiere el uso de CSS .

Luke Dupin
fuente
0

La solución @inoabrian anterior funcionó para mí. Me encontré con una situación en la que actualizaría mi página y mi elemento oculto volvería a aparecer en mi página. Esto es lo que hice para resolverlo.

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

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

Simplemente agregue bind (this) en su función setTimeout, comenzará a funcionar

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

y en cambio de 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>

A

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