¿Cuál es el equivalente de ngShow y ngHide en Angular 2+?

669

Tengo una serie de elementos que quiero que sean visibles en determinadas condiciones.

En AngularJS escribiría

<div ng-show="myVar">stuff</div>

¿Cómo puedo hacer esto en Angular 2+?

1
  • 1
    [hidden] = "! myVar" ... esto funciona en angular 2+ 21 abr.20 a las 20:03
1102

Solo vincula a la hiddenpropiedad

[hidden]="!myVar"

Ver también

cuestiones

hiddenSin embargo, tiene algunos problemas porque puede entrar en conflicto con CSS para la displaypropiedad.

Vea cómo someen el ejemplo de Plunker no se oculta porque tiene un estilo

:host {display: block;}

colocar. (Esto podría comportarse de manera diferente en otros navegadores; probé con Chrome 50)

solución alterna

Puedes arreglarlo agregando

[hidden] { display: none !important;}

A un estilo global en index.html.

otro escollo

hidden="false"
hidden="{{false}}"
hidden="{{isHidden}}" // isHidden = false;

son los mismos que

hidden="true"

y no mostrará el elemento.

hidden="false"asignará la cadena "false"que se considere veraz.
Solo el valor falseo la eliminación del atributo hará que el elemento sea visible.

El uso {{}}también convierte la expresión en una cadena y no funcionará como se esperaba.

Solo el enlace con []funcionará como se esperaba porque esto falsese asigna como en falselugar de "false".

*ngIf vs [hidden]

*ngIfelimina efectivamente su contenido del DOM mientras [hidden]modifica la displaypropiedad y solo indica al navegador que no muestre el contenido, pero el DOM aún lo contiene.

7
  • 11
    *ngIfpuede ser la forma correcta en la mayoría de los casos, pero a veces realmente desea que un elemento esté allí, oculto visualmente. Un estilo CSS con [hidden]{display:none!important}ayudas. Así, por ejemplo, Bootstrap se asegura de que los [hidden]elementos estén realmente ocultos. Ver GitHub 1 de marzo de 2017 a las 13:42
  • Puede encontrar algún problema cuando usa la tubería (myStream | async) dentro de * ng Si eso también usa la tubería (myStream | async) 26 de septiembre de 2017 a las 12:03
  • 1
    eres mi salvador! el uso de * ngIf restablecerá la posición del DOM a la parte superior, pero [oculto] resolvió mi problema y conservó la posición.
    Santosh
    8 dic 2017 a las 15:39
  • 1
    Un caso en el que uno podría querer usar [oculto] sobre * ngIf es cuando está usando HostListener (y desea diferenciar los clics del documento frente a event.target), cuando intenta mostrar y ocultar elementos (como con los menús desplegables personalizados)
    akhouri
    28/08/19 a las 2:30
  • 1
    @Sam, tu comentario es engañoso. Sí, hay peculiaridades sobre el hidden. Pero de acuerdo con el artículo vinculado, es incorrecto decirlo Using hidden is actually not recommended.. 30 sep.20 a las 17:10
170

Utilice el [hidden]atributo:

[hidden]="!myVar"

O puedes usar *ngIf

*ngIf="myVar"

Estas son dos formas de mostrar / ocultar un elemento. La única diferencia es: *ngIfeliminará el elemento de DOM mientras que [hidden]le dirá al navegador que muestre / oculte un elemento usando la displaypropiedad CSS manteniendo el elemento en DOM.

5
  • 4
    [oculto] es agregar condicionalmente un atributo "oculto" al elemento. También podría ser [lo que sea] o [ali]. Lo importante aquí es cargar una regla CSS que mencione que los atributos "ocultos" deben mostrarse: ninguno
    Gabriel
    5 de agosto de 2016 a las 7:14
  • 6
    Tenga en cuenta: * ngIf y [hidden] son ​​fundamentalmente diferentes. ngIf no evaluará el contenido dentro del bloque * ngIf hasta que la condición sea verdadera. Esto es especialmente importante si usa la asynctubería, ya que la suscripción al observable solo se agregará después de que la condición se cumpla.
    Dynalon
    9 de septiembre de 2016 a las 7:59
  • 3
    Una cosa más a tener en cuenta es que * ngIf destruye el componente y tiene que ser recreado, mientras que [hidden] lo mantiene vivo y en memoria. Si tiene un componente que consume muchos recursos, puede ser preferible ocultarlo en lugar de destruirlo. 16/11/2017 a las 15:33
  • 1
    no son lo mismo. 18/08/18 a las 10:37
  • Como se dijo, no es lo mismo en absoluto. Si se está utilizando un componente ngIfy el resultado es falso, no se procesará en absoluto, por lo que ningún código dentro del componente se ejecutará hasta ngIfque se cumpla la condición. 8 de enero a las 14:21
46

Me encuentro en la misma situación con la diferencia de que en mi caso el elemento era un contenedor flexible.Si no es su caso, una solución fácil podría ser

[style.display]="!isLoading ? 'block' : 'none'"

en mi caso, debido al hecho de que muchos de los navegadores que admitimos todavía necesitan el prefijo del proveedor para evitar problemas, busqué otra solución fácil

[class.is-loading]="isLoading"

donde entonces el CSS es tan simple como

&.is-loading { display: none } 

para dejar entonces el estado mostrado manejado por la clase predeterminada.

1
  • 1
    Esto funciona bien con la invalid-feedbackclase bootstrap 4 .
    Jess
    25 oct 2018 a las 14:35
29

Lo siento, no estoy de acuerdo con el enlace a oculto, que se considera inseguro cuando se usa Angular 2. Esto se debe a que el estilo oculto podría sobrescribirse fácilmente, por ejemplo, usando

display: flex;

El enfoque recomendado es usar * ngIf, que es más seguro. Para obtener más detalles, consulte el blog oficial de Angular. 5 errores de novato que deben evitarse con Angular 2

<div *ngIf="showGreeting">
   Hello, there!
</div>
5
  • 12
    Creo que es un error de novato decir que algo está mal antes de conocer los requisitos exactos. Si uno no quiere que un elemento sea eliminado y destruido y agregado y recreado, *ngIfes una mala elección. Pero tiene razón en que las consecuencias deben tenerse en cuenta y señalar los escollos siempre es una buena idea. 25/11/2016 a las 5:43
  • 2
    Yo sé lo que quieres decir. No es mi palabra al respecto, es un error de novato, está tomado del blog oficial de Angular 2. No quiero ofender a nadie. Sin embargo, gracias por señalarlo. 25/11/2016 a las 21:22
  • 9
    Sí, no creo ngIfque responda exactamente a lo que hace esta pregunta. Quiero ocultar algún contenido en una página que incluye un <router-outlet>. Si lo uso ngIf, aparece un error de que no puede encontrar la salida. Necesito que la salida esté oculta hasta que se carguen mis datos, que no esté ausente hasta que se carguen mis datos. 27/11/2016 a las 23:56
  • Estoy de acuerdo contigo, pero el problema que tengo es que quiero mostrar un formulario y ponerle valores si uso el * ng, si tendré el error de que no está definido y con la propiedad oculta está funcionando bien 5 de marzo de 2019 a las 8:49
  • @HazemHASAN, seguro. Entiendo. La solución siempre es condicional. En su caso, no estoy seguro de si es posible verificar si el formulario está allí antes de ejecutar cualquier otro código en él. Se trata de una compensación. ¿Desea una forma más segura de ocultar el formulario que no se compensará accidentalmente con otro estilo en el futuro? ¿O prefiere tener la conveniencia de no verificar si el formulario existe? 5 mar 19 a las 21:08
14

esto es lo que funcionó para mí:

<div [style.visibility]="showThis ? 'visible' : 'hidden'">blah</div>
10
<div [hidden]="myExpression">

myExpression puede establecerse en verdadero o falso

2
  • 2
    <div hidden="{{ myExpression }}">Esto no funcionará, ya que "myExpression" se convertirá en una cadena para ser renderizada en el html. Tanto la cadena "verdadero" como "falso" son veraces, por lo que siempre estará oculta
    Viprus
    6 de septiembre de 2017 a las 13:21
  • 1
    @Viprus No me estoy metiendo contigo, pero he visto este mal uso de la palabra "veraz" aquí antes. Si el selector de CSS es [hidden], y el atributo está presente en HTML y tiene un valor, se aplicará la regla. La veracidad no importa en este caso, ya que no es JS. 23 de agosto a las 21:04
6

Para cualquier otra persona que se encuentre con este problema, así es como lo logré.

import {Directive, ElementRef, Input, OnChanges, Renderer2} from "@angular/core";

@Directive({
  selector: '[hide]'
})
export class HideDirective implements OnChanges {
  @Input() hide: boolean;

  constructor(private renderer: Renderer2, private elRef: ElementRef) {}

  ngOnChanges() {
    if (this.hide) {
      this.renderer.setStyle(this.elRef.nativeElement, 'visibility', 'hidden');
    } else {
      this.renderer.setStyle(this.elRef.nativeElement, 'visibility', 'visible');
    }
  }
}

Usé 'visibility'porque quería preservar el espacio que ocupaba el elemento. Si no desea hacerlo, puede usarlo 'display'y configurarlo en 'none';

Puede vincularlo a su elemento html, dinámicamente o no.

<span hide="true"></span>

o

<span [hide]="anyBooleanExpression"></span>
5

Si su caso es que el estilo no muestra ninguno, también puede usar la directiva ngStyle y modificar la pantalla directamente, lo hice para un Bootstrap DropDown, el UL está configurado para mostrar ninguno.

Así que creé un evento de clic para alternar "manualmente" el UL para mostrar

<div class="dropdown">
    <button class="btn btn-default" (click)="manualtoggle()"  id="dropdownMenu1" >
    Seleccione una Ubicación
    <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" [ngStyle]="{display:displayddl}">
        <li *ngFor="let object of Array" (click)="selectLocation(location)">{{object.Value}}</li>                                
     </ul>
 </div>    

Luego, en el componente, tengo el atributo showDropDown: bool que alterno cada vez, y en función de int, establezco displayDDL para el estilo de la siguiente manera

showDropDown:boolean;
displayddl:string;
manualtoggle(){
    this.showDropDown = !this.showDropDown;
    this.displayddl = this.showDropDown ? "inline" : "none";
}
5

Use hidden como si vincule cualquier modelo con control y especifique css para ello:

HTML:

<input type="button" class="view form-control" value="View" [hidden]="true" />

CSS:

[hidden] {
   display: none;
}
5

De acuerdo con la documentación de Angular 1 de ngShow y ngHide , ambas directivas agregan el estilo css display: none !important;al elemento de acuerdo con la condición de esa directiva (para ngShow agrega css en valor falso, y para ngHide agrega css para valor verdadero).

Podemos lograr este comportamiento usando la directiva Angular 2 ngClass:

/* style.css */
.hide 
{
    display: none !important;
}

<!-- old angular1 ngShow -->
<div ng-show="ngShowVal"> I'm Angular1 ngShow... </div>

<!-- become new angular2 ngClass -->
<div [ngClass]="{ 'hide': !ngShowVal }"> I'm Angular2 ngShow... </div>

<!-- old angular2 ngHide -->
<div ng-hide="ngHideVal"> I'm Angular1 ngHide... </div>

<!-- become new angular2 ngClass -->
<div [ngClass]="{ 'hide': ngHideVal }"> I'm Angular2 ngHide... </div>

Observe que para el showcomportamiento en Angular2 necesitamos agregar !(not) antes de ngShowVal, y para el hidecomportamiento en Angular2 no necesitamos agregar !(not) antes del ngHideVal.

4

Si está utilizando Bootstrap es tan simple como esto:

<div [class.hidden]="myBooleanValue"></div>
1
  • 3
    En bootstrap 4, el uso [hidden]hace lo mismo, así que recomiendo[hidden]
    Vahid
    23/03/18 a las 11:42
4

en bootstrap 4.0 la clase "d-none" = "display: none! important;"

<div [ngClass]="{'d-none': exp}"> </div>
3
<div [hidden]="flagValue">
---content---
</div>
2

para mí, [hidden]=!varnunca ha funcionado.

Entonces, <div *ngIf="expression" style="display:none;">

Y, <div *ngIf="expression">siempre dé resultados correctos.

1

La mejor manera de lidiar con este problema usando ngIf Debido a que esto evitará que ese elemento se renderice en el front-end,

Si usa [hidden]="true"o estilo ocultar [style.display], solo ocultará el elemento en la parte frontal y alguien puede cambiar el valor y visualizarlo fácilmente.En mi opinión, la mejor manera de ocultar el elemento esngIf

<div *ngIf="myVar">stuff</div>

y también si tiene varios elementos (necesita implementar más también) puede usar la <ng-template>opción

<ng-container *ngIf="myVar; then loadAdmin else loadMenu"></ng-container>
<ng-template #loadMenu>
     <div>loadMenu</div>
</ng-template>

<ng-template #loadAdmin>
     <div>loadAdmin</div>
</ng-template>  

código de plantilla de muestra

1
  • Estoy de acuerdo con usted, se prefiere usar * ngIf en lugar de estar oculto por alguna razón de rendimiento para la optimización del DOM 13 jul a las 22:20
1

Mi problema fue mostrar / ocultar una tabla de mat en un clic de botón usando <ng-container * ngIf = "myVar">. La 'carga' de la tabla fue muy lenta con 300 registros a los 2-3 segundos.

Los datos se cargan usando una suscripción en ngOnInit (), y están disponibles y listos para usarse en la plantilla, sin embargo, la 'carga' de la tabla en la plantilla se volvió cada vez más lenta con el aumento en el número de filas.

Mi solución fue reemplazar el * ngIf con:

<div [style.display]="activeSelected ? 'block' : 'none'">

. Ahora la tabla se carga instantáneamente cuando se hace clic en el botón.

0

Hay dos ejemplos en documentos angulares https://angular.io/guide/structural-directives#why-remove-rather-than-hide

A directive could hide the unwanted paragraph instead by setting its display style to none.

<p [style.display]="'block'">
  Expression sets display to "block".
  This paragraph is visible.
</p>

<p [style.display]="'none'">
  Expression sets display to "none".
  This paragraph is hidden but still in the DOM.
</p>

Puede usar [style.display] = "'block'" para reemplazar ngShow y [style.display] = "'none'" para reemplazar ngHide.

0

Si solo desea usar las directivas hidden/ simétricas con las shownque vino AngularJS, sugiero escribir una directiva de atributo para simplificar las plantillas de esta manera (probada con Angular 7):


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

@Directive({ selector: '[shown]' })
export class ShownDirective {
  @Input() public shown: boolean;

  @HostBinding('attr.hidden')
  public get attrHidden(): string | null {
    return this.shown ? null : 'hidden';
  }
}

Muchas de las otras soluciones son correctas. Usted debe utilizar *ngIfsiempre que sea posible. El uso del hiddenatributo puede tener aplicados estilos inesperados, pero a menos que esté escribiendo componentes para otros, probablemente sepa si es así. Entonces, para que esta showndirectiva funcione, también querrá asegurarse de agregar:

[hidden]: {
  display: none !important;
}

a tus estilos globales en algún lugar.

Con estos puedes usar la directiva así:

<div [shown]="myVar">stuff</div>

con la versión simétrica (y opuesta) así:

<div [hidden]="myVar">stuff</div>

Para agregar a los debería , también debe usar un prefijo como so [acmeShown]vs just [shown].

La razón principal por la que utilicé una showndirectiva de atributo es para convertir el código AngularJS a Angular -Y- cuando el contenido que se está ocultando contiene componentes de contenedor que causan viajes de ida y vuelta XHR. La razón por la que no lo uso [hidden]="!myVar"es que a menudo es más complicado como: [hidden]="!(myVar || yourVar) && anotherVar" - yes I can invert that, but it is more error prone.[mostrado] `es simplemente más fácil de pensar.

0

Tienes dos opciones:

Primera opción

[style.display]="!isShow ? 'block' : 'none'"

Segunda opción

myVarible puede ser booleano

[hidden]="!myVarible"
-1

Para ocultar y mostrar div en el botón, haga clic en angular 6.

Código HTML

<button (click)="toggleElement()">FormatCell</button>
<div class="ruleOptionsPanel" *ngIf="isShow">
   <table>
      <tr>
         <td>Name</td>
         <td>Ram</td>
      </tr>
   </table>
</div>

Código AppComponent.ts

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent{
   isShow=false;
   toggleElement():void
   {
      this.isShow = !this.isShow
   }
}

esto funciona para mí y es una forma de reemplazar ng-hide y ng-show en angular2 +

2
  • Está utilizando ngIf, que es diferente de ngShow. NgIf eliminará / agregará el elemento del DOM. Esto no es lo mismo que ngShow / ngHide, que solo agregará / eliminará estilos Css al elemento. 28/01/19 a las 17:19
  • El ejemplo es demasiado largo y específico. 18/06/19 a las 11:06