Qual é o equivalente de ngShow e ngHide no Angular 2+?

570

Eu tenho vários elementos que quero que sejam visíveis sob certas condições.

No AngularJS eu escreveria

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

Como posso fazer isso no Angular 2+?

Mihai Răducanu
fonte
[hidden] = "! myVar" .. isso funciona em angulares 2+
Atualizado em 21/04

Respostas:

951

Basta vincular à hiddenpropriedade

[hidden]="!myVar"

Veja também

problemas

hiddentem alguns problemas porque pode entrar em conflito com o CSS da displaypropriedade

Veja como someno exemplo do Plunker não fica oculto porque tem um estilo

:host {display: block;}

conjunto. (Isso pode se comportar de maneira diferente em outros navegadores - testei com o Chrome 50)

Gambiarra

Você pode corrigi-lo adicionando

[hidden] { display: none !important;}

Para um estilo global em index.html.

outra armadilha

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

são os mesmos que

hidden="true"

e não mostrará o elemento

hidden="false"atribuirá a string "false"que é considerada verdadeira.
Somente o valor falseou a remoção do atributo realmente tornarão o elemento visível.

O uso {{}}também converte a expressão em uma sequência e não funcionará conforme o esperado.

Somente a ligação com []funcionará conforme o esperado, pois isso falseé atribuído como em falsevez de"false" .

*ngIf vs [hidden]

*ngIfremove efetivamente seu conteúdo do DOM enquanto [hidden]modifica a displaypropriedade e instrui apenas o navegador a não mostrar o conteúdo, mas o DOM ainda o contém.

Günter Zöchbauer
fonte
21
Usar oculto não é realmente recomendado. angularjs.blogspot.com/2016/04/…
Sam
7
*ngIfpode ser a maneira correta na maioria dos casos, mas às vezes você realmente quer que um elemento esteja lá, visualmente oculto. Um estilo CSS com [hidden]{display:none!important}ajuda. É assim, por exemplo, como o Bootstrap garante que os [hidden]elementos estejam realmente ocultos. Veja GitHub
CunningFatalist
Você pode encontrar algum problema ao usar (myStream | assíncrona) tubo dentro de * ngIf que também utiliza (myStream | assíncrona) tubos
Pavel Blagodov
1
você é meu salvador! usar * ngIf redefinirá a posição DOM para o topo, mas [oculto] resolveu meu problema e preservou a posição.
Santosh
1
Um caso em que você pode querer usar [hidden] over * ngIf é quando você está usando HostListener (e deseja diferenciar cliques de documento vs event.target), ao tentar mostrar e ocultar elementos (como em drop downs personalizados)
akhouri
141

Use o [hidden]atributo:

[hidden]="!myVar"

Ou você pode usar *ngIf

*ngIf="myVar"

Estas são duas maneiras de mostrar / ocultar um elemento. A única diferença é: *ngIfremoverá o elemento do DOM e [hidden]instruirá o navegador a mostrar / ocultar um elemento usando a displaypropriedade CSS mantendo o elemento no DOM.

Ali Shahzad
fonte
3
[hidden] está adicionando, na condição, um atributo "hidden" ao elemento. Também poderia ser [tanto faz] ou [ali]. O importante aqui é carregar uma regra CSS que mencione atributos "ocultos" deve ser exibida: none
Gabriel
5
Tenha em mente: * ngIf e [hidden] são fundamentalmente diferentes. ngIf não avaliará o conteúdo dentro do bloco * ngIf até que a condição seja verdadeira. Isso é especialmente importante se você usar o asynccanal, pois a assinatura do observável será adicionada somente depois que a condição se tornar realidade!
Dynalon 9/09/16
2
Mais uma coisa a levar em consideração é que * ngIf destrói o componente e ele deve ser recriado, enquanto [oculto] o mantém vivo e na memória. Se você possui um componente com muitos recursos, pode ser preferível escondê-lo em vez de destruí-lo
Michael Kork.
1
eles não são a mesma coisa.
Kamuran Sönecek 18/08/19
36

Eu me encontro na mesma situação com a diferença do que no meu caso, o elemento era um contêiner flexível. Se não for o seu caso, uma solução fácil pode ser

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

no meu caso, devido ao fato de que muitos navegadores que suportamos ainda precisam do prefixo do fornecedor para evitar problemas, procurei outra solução fácil

[class.is-loading]="isLoading"

onde então o CSS é simples como

&.is-loading { display: none } 

para sair, o estado exibido é tratado pela classe padrão.

Vale Steve
fonte
1
Isso funciona bem com a invalid-feedbackclasse bootstrap 4 .
Jess
25

Desculpe, eu tenho que discordar da ligação a hidden, que é considerada insegura ao usar o Angular 2. Isso ocorre porque o estilo oculto pode ser substituído facilmente, por exemplo, usando

display: flex;

A abordagem recomendada é usar * ngIf, que é mais seguro. Para mais detalhes, consulte o blog oficial da Angular. 5 erros de novato a serem evitados com o Angular 2

<div *ngIf="showGreeting">
   Hello, there!
</div>
Tim Hong
fonte
12
Eu acho que é um erro de novato dizer que algo está ruim antes de conhecer os requisitos exatos. Se alguém não quiser que um elemento seja removido, destruído, adicionado e recriado, *ngIfé uma má escolha. Mas você está certo de que as consequências precisam ser consideradas e apontar armadilhas é sempre uma boa idéia.
Günter Zöchbauer 25/11
2
Eu sei o que você quer dizer. Não é minha palavra que se trata de um erro de iniciante, é retirado do blog oficial do Angular 2. Não pretendo ofender ninguém. Obrigado por apontar, no entanto.
Tim Hong
9
Sim, acho que não ngIfresponde exatamente o que essa pergunta está fazendo. Quero ocultar algum conteúdo em uma página que inclua a <router-outlet>. Se eu usar ngIf, recebo um erro que não consegue encontrar a tomada. Eu preciso que a tomada fique oculta até que meus dados sejam carregados, não ausente até que meus dados sejam carregados.
precisa
Eu concordo com você, mas o problema que tenho é que quero mostrar um formulário e colocar valores nele se eu usar o * ngIf Terei o erro de que não está definido e com a propriedade oculta está funcionando bem
Hazem HASAN 5/03/19
@HazemHASAN, com certeza. Compreendo. A solução é sempre condicional. No seu caso, não tenho certeza se é possível apenas verificar se o formulário existe antes de executar qualquer outro código nele. É tudo sobre o trade-off. Deseja uma maneira mais segura de ocultar acidentalmente o formulário que não será compensado por outro estilo no futuro? Ou você prefere ter a conveniência de não verificar se o formulário existe?
Tim Hong
4

Se o seu caso é que o estilo é display none, você também pode usar a diretiva ngStyle e modificar a tela diretamente, fiz isso para um DropDown de inicialização, o UL está definido para exibir nenhum.

Então, criei um evento de clique para alternar "manualmente" o UL para exibir

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

Em seguida, no componente eu tenho o atributo showDropDown: bool que eu alterno todas as vezes e, com base em int, defina o displayDDL para o estilo da seguinte maneira

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

De acordo com a documentação Angular 1 do ngShow e ngHide , essas duas diretivas adicionam o estilo cssdisplay: none !important; ao elemento de acordo com a condição dessa diretiva (para ngShow adiciona css em valor falso e para ngHide adiciona css para valor verdadeiro).

Podemos conseguir esse comportamento usando a diretiva 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 o showcomportamento em Angular2, precisamos adicionar !(não) antes do ngShowVal, e para o hidecomportamento em Angular2, não precisamos adicionar !(não) antes do ngHideVal.

Gil Epshtain
fonte
4
<div [hidden]="myExpression">

myExpression pode ser definido como verdadeiro ou falso

Niyaz
fonte
2
<div hidden="{{ myExpression }}">Isso não funcionará, pois "myExpression" será convertido em uma string a ser renderizada no html. Tanto a string "true" quanto a "false" são verdadeiras, portanto sempre estarão ocultas
#
3

Se você estiver usando o Bootstrap, é tão simples quanto isto:

<div [class.hidden]="myBooleanValue"></div>
Gian Marco Gherardi
fonte
3
Na inicialização 4 usando [hidden]faz o mesmo então eu recomendo[hidden]
Vahid
3

no bootstrap 4.0, a classe "d-none" = "display: none! important;"

<div [ngClass]="{'d-none': exp}"> </div>
63RMAN
fonte
3

Para qualquer um que tropeçar nessa questão, foi assim que eu consegui.

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

Eu usei 'visibility'porque queria preservar o espaço ocupado pelo elemento. Se você não desejar, basta usar 'display'e configurá-lo para 'none';

Você pode vinculá-lo ao seu elemento html, dinamicamente ou não.

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

ou

<span [hide]="anyBooleanExpression"></span>
Anjil Dhamala
fonte
2

Use hidden como você liga qualquer modelo com controle e especifique css para ele:

HTML:

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

CSS:

[hidden] {
   display: none;
}
Sandip - Desenvolvedor Full Stack
fonte
2

Isto é o que funcionou para mim:

<div [style.visibility]="showThis ? 'visible' : 'hidden'">blah</div>
Alex
fonte
1
<div [hidden]="flagValue">
---content---
</div>
Chirag
fonte
1

para mim, [hidden]=!varnunca funcionou.

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

E, <div *ngIf="expression">sempre dê resultados corretos.

Priyanka Arora
fonte
0

Existem dois exemplos em documentos angulares https://angular.io/guide/structural-directives#why-remove-rather-than-hide

Uma diretiva pode ocultar o parágrafo indesejado, definindo seu estilo de exibição como nenhum.

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

Você pode usar [style.display] = "'block'" para substituir o ngShow e [style.display] = "'none'" para substituir o ngHide.

koo
fonte
0

A melhor maneira de lidar com esse problema usando ngIf Como isso evita que o elemento seja renderizado no front-end,

Se você usar [hidden]="true"ou estilizar o hide, [style.display]ele ocultará apenas o elemento no front end e alguém poderá alterar o valor e visualizá-lo facilmente. Na minha opinião, a melhor maneira de ocultar o elemento éngIf

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

e também Se você tiver vários elementos (é necessário implementar outra coisa também), você pode usar a <ng-template>opção

<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 exemplo do modelo ng

DeC
fonte
0

Se você quiser apenas usar as diretivas simétricas hidden/ shownque o AngularJS veio, sugiro escrever uma diretiva de atributo para simplificar os modelos assim (testados no 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';
  }
}

Muitas das outras soluções estão corretas. Você deve usar *ngIfsempre que possível. O uso do hiddenatributo pode ter estilos inesperados aplicados, mas, a menos que você esteja escrevendo componentes para outras pessoas, provavelmente já sabe se está. Portanto, para que essa showndiretiva funcione, você também precisará adicionar:

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

aos seus estilos globais em algum lugar.

Com eles, você pode usar a diretiva da seguinte maneira:

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

com a versão simétrica (e oposta) da seguinte forma:

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

Para adicionar ao shoulds - você também deve nos usar um prefixo assim [acmeShown]vs just [shown].

O principal motivo pelo qual usei uma showndiretiva de atributo é converter o código AngularJS em Angular -AND- quando o conteúdo oculto contém componentes de contêiner que causam viagens de ida e volta ao XHR. A razão pela qual eu não uso apenas [hidden]="!myVar"é que, com frequência, é mais complicado, como: [hidden]="!(myVar || yourVar) && anotherVar" - yes I can invert that, but it is more error prone.[mostrado] `é simplesmente mais fácil de pensar.

nephiw
fonte
-1

Para ocultar e mostrar o botão div on, clique na angular 6.

Código HTML

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

Código .ts do componente

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

isso funciona para mim e é uma maneira de substituir ng-hide e ng-show em angular6.

desfrutar...

obrigado

Manoj Gupta
fonte
Você está usando o ngIf - que é diferente do ngShow. NgIf removerá / adicionará o elemento do DOM. Não é o mesmo que ngShow / ngHide, que adicionará / removerá apenas estilos CSS no elemento.
Gil Epshtain 28/01/19
O exemplo é muito longo e muito específico.
Masterxilo 18/06/19