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

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

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?


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>

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.


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

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>

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 .


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

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>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.