¿Cuál es la diferencia entre ng-if y ng-show / ng-hide

Intento entender la diferencia entre ng-if y ng-show / ng-hide , pero me parecen iguales.

¿Hay alguna diferencia que deba tener en cuenta al elegir usar una u otra?

ngIf

La directiva ngIf elimina o recrea una parte del árbol DOM en función de una expresión. Si la expresión asignada a ngIf evalúa como un valor falso, entonces el elemento se elimina del DOM, de lo contrario, una copia del elemento se reinserta en el DOM.

  

Cuando se elimina un elemento usando ngIf se destruye su scope y se crea un nuevo ámbito cuando se restaura el elemento. El scope creado dentro de ngIf hereda de su ámbito principal usando herencia de prototipos.

Si ngModel se utiliza dentro de ngIf para vincularse a una primitiva de JavaScript definida en el ámbito primario, cualquier modificación realizada en la variable dentro del scope secundario no afectará el valor en el ámbito principal, por ejemplo

  

Para evitar esta situación y actualizar el modelo en el ámbito principal desde dentro del ámbito secundario, use un objeto:

  

O bien, $parent variable $parent para hacer referencia al objeto de ámbito primario:

  

ngShow

La directiva ngShow muestra u oculta el elemento HTML dado en función de la expresión proporcionada al atributo ngShow . El elemento se muestra u oculta al eliminar o agregar la clase CSS de ng-hide en el elemento. La .ng-hide CSS está predefinida en AngularJS y establece el estilo de visualización en ninguno (usando un indicador de !important ).

  

Cuando la expresión ngShow evalúa como false , la clase ng-hide CSS se agrega al atributo de class en el elemento, lo que hace que se oculte. Cuando es true , la clase CSS de ng-hide se elimina del elemento, lo que hace que el elemento no aparezca oculto.

Tal vez un punto interesante para hacer, es la diferencia entre las prioridades entre ambos.

Por lo que puedo decir, la directiva ng-if tiene una de las prioridades más altas (si no la más alta) de todas las directivas angulares. Lo que significa que se ejecutará PRIMERO antes que todas las demás directivas de menor prioridad. El hecho de que se ejecute FIRST significa que, efectivamente, el elemento se elimina antes de que se procesen las directivas internas . O al menos: eso es lo que hago de eso.

Observé y usé esto en la interfaz de usuario que estoy construyendo para mi cliente actual. Toda la interfaz de usuario está bastante cargada, y tenía ng-show y ng-hide por todas partes. No voy a entrar en demasiados detalles, pero construí un componente genérico, que podría administrarse usando la configuración JSON, así que tuve que hacer algunos cambios dentro de la plantilla. Hay un presente de repetición ng, y dentro de la repetición ng, se muestra una tabla, que tiene una gran cantidad de ng-shows, ng-hides e incluso ng-switches presentes. Querían mostrar al menos 50 repeticiones en la lista, lo que daría como resultado la resolución de más o menos 1500-2000 directivas. Comprobé el código, y el backend de Java + JS personalizado en la parte frontal tardaría unos 150 ms en procesar los datos, y luego Angular masticó unos 2-3 segundos en él, antes de mostrarlo. El cliente no se quejó, pero me horroricé 🙂

En mi búsqueda, tropecé con la directiva ng-if. Ahora, tal vez sea mejor señalar que, en el momento de concebir esta interfaz de usuario, no había ng, si estaba disponible. Debido a que ng-show y ng-hide tenían funciones en ellos, que devolvían booleanos, podía reemplazarlos fácilmente con ng-if. Al hacerlo, todas las directivas internas parecían dejar de evaluarse. Eso significaba que volví a aproximadamente un tercio de todas las directivas que se estaban evaluando, y por lo tanto, la IU aceleró hasta aproximadamente 500 ms – 1 segundo de tiempo de carga. (No tengo manera de determinar los segundos exactos)

Tenga en cuenta: el hecho de que las directivas no se evalúan, es una suposición educada sobre lo que está sucediendo debajo.

Por lo tanto, en mi opinión: si necesita que el elemento esté presente en la página (es decir, para verificar el elemento, o lo que sea), pero simplemente esté oculto, use ng-show / ng-hide. En todos los demás casos, use ng-if.

La directiva ng-if elimina el contenido de la página y ng-show/ng-hide utiliza la propiedad de display CSS para ocultar el contenido.

Esto es útil en caso de que quiera usar :first-child pseudo selectores de :first-child y :last-child para el estilo.

@EdSpencer es correcto. Si tiene muchos elementos y utiliza ng, si solo desea crear instancias de los relevantes, está guardando recursos. @CodeHater también es algo correcto, si va a eliminar y mostrar un elemento con mucha frecuencia, ocultarlo en lugar de eliminarlo podría mejorar el rendimiento.

El caso de uso principal que encuentro para ng-if es que me permite validar limpiamente y eliminar un elemento si el contenido es ilegal. Por ejemplo, podría hacer referencia a una variable nula de nombre de imagen y arrojaría un error, pero si hago ng-if y verifico si es nulo, todo está bien. Si hiciera un ng-show, el error aún se dispararía.

Una cosa importante a tener en cuenta acerca de ng-if y ng-show es que al usar controles de formulario es mejor usar ng-if porque elimina completamente el elemento de la dom.

Esta diferencia es importante porque si crea un campo de entrada con required="true" y luego establece ng-show="false" para ocultarlo, Chrome arrojará el siguiente error cuando el usuario intente enviar el formulario:

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

El motivo es que el campo de entrada está presente y es required pero como está oculto, Chrome no puede enfocarlo. Esto literalmente puede romper su código ya que este error detiene la ejecución del script. ¡Así que ten cuidado!

@Gajus Kuizinas y @CodeHater son correctos. Aquí solo estoy dando un ejemplo. Mientras trabajamos con ng-if, si el valor asignado es falso, entonces los elementos html completos se eliminarán de DOM. y si el valor asignado es verdadero, entonces los elementos html serán visibles en el DOM. Y el scope será diferente en comparación con el scope principal. Pero en el caso de ng-show, solo mostrará y ocultará los elementos en función del valor asignado. Pero siempre permanece en el DOM. Solo la visibilidad cambia según el valor asignado.

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

Espero que este ejemplo te ayude a entender los ámbitos. Intente dar valores falsos a ng-show y ng-if y verifique el DOM en la consola. Intente ingresar los valores en los cuadros de entrada y observe la diferencia.

  

Hola Plunker!

  

ng-show=true ::

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

  1. ng-if si es falso eliminará elementos de DOM. Esto significa que todos sus eventos, las directivas asociadas a esos elementos se perderán. Por ejemplo, ng-clic en uno de los elementos secundarios, cuando ng-if se evalúa como falso, ese elemento se eliminará de DOM y, nuevamente, cuando sea verdadero, se volverá a crear.

  2. ng-show / ng-hide no elimina los elementos de DOM. Utiliza estilos CSS (.ng-hide) para ocultar / mostrar elementos. De esta forma sus eventos, las directivas que se adjuntaron a los niños no se perderán.

  3. ng-if crea un ámbito hijo mientras que ng-show / ng-hide no.

De hecho, esa directiva ng-if , a diferencia de ng-show , crea su propio scope, conduce a una interesante diferencia práctica:

 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 tener en cuenta, una cosa que me sucedió ahora: ng-show esconde el contenido a través de css, sí, pero dio como resultado extraños fallos en los botones de div.

Tenía una tarjeta con dos botones en la parte inferior y, dependiendo del estado real, una se intercambia con una tercera, ejemplo, botón editar con una nueva entrada. Usando ng-show = false para ocultar el izquierdo (presente primero en el archivo) sucedió que el siguiente botón terminó con el borde derecho fuera de la tarjeta. ng-si lo corrige al no incluir el código en absoluto. (Acabo de marcar aquí si hay algunas sorpresas ocultas usando ng-si en lugar de ng-show)

ng-show y ng-hide funcionan de manera opuesta. Pero la diferencia entre ng-hide o ng-show con ng-if es, si usamos ng-si el elemento se creará en el dom pero con el elemento ng-hide / ng-show se ocultará por completo.

 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. 

Una diferencia interesante en ng-if y ng-show es:

SEGURIDAD

Los elementos DOM presentes en el bloque ng-if no se representarán en caso de que su valor sea falso

donde, como en el caso de ng-show, el usuario puede abrir su ventana Inspeccionar elemento y establecer su valor en VERDADERO.

Y con un grito, se muestra todo el contenido que se pretendía ocultar, que es una violación de seguridad. 🙂