qual é a diferença entre ng-if e ng-show / ng-hide

Eu estou tentando entender a diferença entre ng-if e ng-show / ng-hide , mas eles parecem o mesmo para mim.

Existe alguma diferença que devo ter em mente ao escolher usar um ou outro?

ngIf

A diretiva ngIf remove ou recria uma parte da tree DOM com base em uma expressão. Se a expressão atribuída a ngIf avaliada como um valor falso, o elemento será removido do DOM, caso contrário, um clone do elemento será reinserido no DOM.

  

Quando um elemento é removido usando ngIf seu escopo é destruído e um novo escopo é criado quando o elemento é restaurado. O escopo criado dentro do ngIf herda de seu escopo pai usando inheritance prototypal.

Se ngModel for usado dentro de ngIf para se ligar a uma primitiva JavaScript definida no escopo pai, quaisquer modificações feitas na variável dentro do escopo filho não afetarão o valor no escopo pai, por exemplo

  

Para contornar essa situação e atualizar o modelo no escopo pai de dentro do escopo filho, use um object:

  

Ou variável $parent para referenciar o object de escopo pai:

  

ngShow

A diretiva ngShow mostra ou oculta o elemento HTML fornecido com base na expressão fornecida ao atributo ngShow . O elemento é mostrado ou oculto removendo ou adicionando a class CSS ng-hide ao elemento. A class CSS .ng-hide é predefinida no AngularJS e define o estilo de exibição como none (usando um sinalizador !important ).

  

Quando a expressão ngShow avaliada como false , a class CSS ng-hide é adicionada ao atributo de class no elemento, fazendo com que ela fique oculta. Quando true , a class CSS ng-hide é removida do elemento, fazendo com que o elemento não apareça oculto.

Talvez um ponto interessante a se fazer seja a diferença entre as prioridades entre ambos.

Tanto quanto eu posso dizer, a diretiva ng-if tem uma das maiores (se não a mais alta) prioridade de todas as diretivas angulares. O que significa: ele será executado PRIMEIRO antes de todas as outras diretivas de prioridade mais baixa. O fato de ser executado PRIMEIRO significa que, efetivamente, o elemento é removido antes que qualquer diretiva interna seja processada. Ou pelo menos: é o que eu faço disso.

Eu observei e usei isso na interface do usuário que estou criando para meu cliente atual. Toda a interface do usuário é bastante complexa, e tinha ng-show e ng-hide por toda parte. Para não entrar em muitos detalhes, mas eu construí um componente genérico, que poderia ser gerenciado usando a configuração JSON, então eu tive que fazer algumas mudanças dentro do template. Há um ng-repete presente, e dentro do ng-repeat, uma tabela é mostrada, que tem muitos ng-shows, ng-hides e até ng-switches presentes. Eles queriam mostrar pelo menos 50 repetições na lista, o que resultaria em mais ou menos 1500-2000 diretivas a serem resolvidas. Eu verifiquei o código, e o Java backend + custom JS na frente levaria cerca de 150ms para processar os dados, e então o Angular iria mastigar uns 2-3 segundos, antes de exibir. O cliente não reclamou, mas fiquei chocado 🙂

Na minha busca, tropecei na diretiva ng-if. Agora, talvez seja melhor ressaltar que, no ponto de conceber essa interface, não havia ng-se disponível. Como o ng-show e o ng-hide tinham funções neles, que retornavam booleanos, eu poderia facilmente substituí-los todos com ng-if. Ao fazer isso, todas as diretivas internas pareciam não ser mais avaliadas. Isso significava que eu voltava para cerca de um terço de todas as diretivas sendo avaliadas e, assim, a interface do usuário acelerava para cerca de 500 ms – 1 segundo de tempo de carregamento. (Eu não tenho como determinar segundos exatos)

Observe: o fato de as diretivas não serem avaliadas é um palpite sobre o que está acontecendo embaixo.

Então, na minha opinião: se você precisa que o elemento esteja presente na página (por exemplo: para verificar o elemento, ou qualquer outro), mas simplesmente fique oculto, use ng-show / ng-hide. Em todos os outros casos, use ng-if.

A diretiva ng-if remove o conteúdo da página e ng-show/ng-hide usa a propriedade de display CSS para ocultar o conteúdo.

Isso é útil caso você queira usar :first-child e :last-child pseudo selectors to style.

@ Edspencer está correto. Se você tem muitos elementos e usa ng-if para apenas instanciar os relevantes, você está salvando resources. @CodeHater também está um pouco correto, se você for remover e mostrar um elemento com muita frequência, ocultá-lo em vez de removê-lo poderá melhorar o desempenho.

O principal caso de uso que encontro para ng-if é que me permite validar e eliminar um elemento de forma limpa se o conteúdo for ilegal. Por exemplo, eu poderia fazer referência a uma variável de nome de imagem nula e isso vai lançar um erro, mas se eu ng-if e verificar se é nulo, está tudo bem. Se eu fiz um ng-show, o erro ainda triggersria.

Uma coisa importante a se notar sobre ng-if e ng-show é que ao usar controles de formulário é melhor usar ng-if porque ele remove completamente o elemento do dom.

Essa diferença é importante porque, se você criar um campo de input com required="true" e, em seguida, definir ng-show="false" para ocultá-lo, o Chrome apresentará o seguinte erro quando o usuário tentar enviar o formulário:

 An invalid form control with name='' is not focusable. 

O motivo é que o campo de input está presente e é required mas, como está oculto, o Chrome não pode se concentrar nele. Isso pode literalmente quebrar seu código, pois esse erro interrompe a execução do script. Por isso tem cuidado!

@Gajus Kuizinas e @CodeHater estão corretos. Aqui estou apenas dando um exemplo. Enquanto estivermos trabalhando com ng-if, se o valor designado for falso, todos os elementos html serão removidos do DOM. e se o valor atribuído for true, os elementos html ficarão visíveis no DOM. E o escopo será diferente em comparação ao escopo pai. Mas no caso do ng-show, ele mostrará e ocultará os elementos com base no valor atribuído. Mas sempre fica no DOM. Apenas a visibilidade muda de acordo com o valor atribuído.

http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview

Espero que este exemplo ajude você a entender os escopos. Tente dar valores falsos para ng-show e ng-if e verifique o DOM no console. Tente inserir os valores nas checkboxs de input e observe a diferença.

  

Olá Plunker!

  

ng-show=true ::

ng-if=true ::
{{data}}

  1. ng-if se false removerá elementos do DOM. Isso significa que todos os seus events, diretivas anexadas a esses elementos serão perdidos. Por exemplo, ng-click para um dos elementos filhos, quando ng-if é avaliado como false, esse elemento será removido do DOM e, novamente, quando é verdadeiro, é recriado.

  2. ng-show / ng-hide não remove os elementos do DOM. Ele usa estilos CSS (.ng-hide) para ocultar / mostrar elementos. Dessa forma, seus events, diretivas que foram anexadas às crianças, não serão perdidos.

  3. ng-if cria um escopo filho enquanto ng-show / ng-hide não.

Fato, que ng-if diretiva ng-if , ao contrário do ng-show , cria seu próprio escopo, leva a uma diferença prática interessante:

 angular.module('app', []).controller('ctrl', function($scope){ $scope.delete = function(array, item){ array.splice(array.indexOf(item), 1); } }) 
  

ng-if:

  • {{show}}

ng-show:

  • {{show}}

ng-if with $parent:

  • {{show}}

Para notar, uma coisa que aconteceu comigo agora: ng-show esconde o conteúdo via css, sim, mas resultou em falhas estranhas em div supostamente ser botões.

Eu tinha um cartão com dois botões na parte inferior e, dependendo do estado real, um é trocado por um terceiro botão de edição de exemplo com uma nova input. Usando ng-show = false para esconder o esquerdo (presente primeiro no arquivo) aconteceu que o botão a seguir acabou com a borda direita fora do cartão. ng-se corrige isso, não incluindo o código. (Apenas verifiquei aqui se há algumas surpresas escondidas usando ng-if em vez de ng-show)

ng-show e ng-hide funcionam de maneira oposta. Mas a diferença entre ng-hide ou ng-show com ng-if é, se usarmos ng-if, então o elemento criado no dom mas com o elemento ng-hide / ng-show ficará completamente oculto.

 ng-show=true/ng-hide=false: Element will be displayed ng-show=false/ng-hide=true: element will be hidden ng-if =true element will be created ng-if= false element will be created in the dom. 

Uma diferença interessante em ng-if e ng-show é:

SEGURANÇA

Elementos DOM presentes no bloco ng-if não serão renderizados no caso de seu valor ser falso

onde, como no caso do ng-show, o usuário pode abrir sua janela Inspect Element e definir seu valor como TRUE.

E com um grito, todo o conteúdo que deveria ficar oculto é exibido, o que é uma violação de segurança. 🙂