¿Cuál es la diferencia entre ng-if y ng-show/ng-hide?
Estoy tratando de entender la diferencia entre ng-if
y ng-show
/ ng-hide
, pero me parecen iguales.
¿Hay alguna diferencia que debo tener en cuenta al elegir usar uno u otro?
ngSi
La ngIf
directiva elimina o recrea una parte del árbol DOM basándose en una expresión. Si la expresión asignada a ngIf
se evalúa como un valor falso, entonces el elemento se elimina del DOM; de lo contrario, se reinserta un clon del elemento en el DOM.
<!-- when $scope.myValue is truthy (element is restored) -->
<div ng-if="1"></div>
<!-- when $scope.myValue is falsy (element is removed) -->
<div ng-if="0"></div>
Cuando se elimina un elemento, ngIf
su alcance se destruye y se crea un nuevo alcance cuando se restaura el elemento. El ámbito creado dentro ngIf
hereda de su ámbito principal mediante herencia prototípica.
Si ngModel
se usa dentro ngIf
para vincularse a una primitiva de JavaScript definida en el ámbito principal, cualquier modificación realizada a la variable dentro del ámbito secundario no afectará el valor en el ámbito principal, por ejemplo.
<input type="text" ng-model="data">
<div ng-if="true">
<input type="text" ng-model="data">
</div>
Para solucionar esta situación y actualizar el modelo en el ámbito principal desde dentro del ámbito secundario, utilice un objeto:
<input type="text" ng-model="data.input">
<div ng-if="true">
<input type="text" ng-model="data.input">
</div>
O $parent
variable para hacer referencia al objeto de alcance principal:
<input type="text" ng-model="data">
<div ng-if="true">
<input type="text" ng-model="$parent.data">
</div>
ngMostrar
La ngShow
directiva muestra u oculta el elemento HTML dado según la expresión proporcionada al ngShow
atributo. El elemento se muestra u oculta eliminando o agregando la ng-hide
clase CSS al elemento. La .ng-hide
clase CSS está predefinida en AngularJS y establece el estilo de visualización en ninguno (usando una !important
bandera).
<!-- when $scope.myValue is truthy (element is visible) -->
<div ng-show="1"></div>
<!-- when $scope.myValue is falsy (element is hidden) -->
<div ng-show="0" class="ng-hide"></div>
Cuando la ngShow
expresión se evalúa, false
la ng-hide
clase CSS se agrega al class
atributo del elemento, lo que hace que quede oculto. Cuando true
, la ng-hide
clase CSS se elimina del elemento, lo que hace que el elemento no aparezca oculto.
Quizás un punto interesante a destacar es la diferencia entre las prioridades de ambos.
Hasta donde puedo decir, la directiva ng-if tiene una de las prioridades más altas (si no la más alta) de todas las directivas Angular. Lo que significa: se ejecutará PRIMERO antes que todas las demás directivas de menor prioridad. El hecho de que se ejecute PRIMERO significa que, efectivamente, el elemento se elimina antes de que se procesen las directivas internas . O al menos: eso es lo que pienso de ello.
Observé y usé esto en la interfaz de usuario que estoy creando para mi cliente actual. Toda la interfaz de usuario está bastante repleta y tenía ng-show y ng-hide por todas partes. No quiero entrar en demasiados detalles, pero construí un componente genérico, que se podía administrar usando la configuración JSON, así que tuve que hacer algunos cambios dentro de la plantilla. Hay una repetición ng presente, y dentro de la repetición ng, se muestra una tabla que tiene muchos espectáculos ng, ocultaciones ng e incluso interruptores ng presentes. Querían mostrar al menos 50 repeticiones en la lista, lo que daría como resultado aproximadamente entre 1.500 y 2.000 directivas por resolver. Revisé el código y el backend de Java + JS personalizado en el frente tardaría unos 150 ms en procesar los datos, y luego Angular los masticaría entre 2 y 3 segundos antes de mostrarlos. El cliente no se quejó, pero me horroricé :-)
En mi búsqueda, me topé 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-if disponible. Debido a que ng-show y ng-hide tenían funciones que devolvían valores booleanos, podría reemplazarlas todas fácilmente con ng-if. Al hacerlo, parecía que ya no se evaluaban todas las directivas internas. Eso significó que reduje a aproximadamente un tercio de todas las directivas evaluadas y, por lo tanto, la interfaz de usuario se aceleró a aproximadamente 500 ms (tiempo de carga de 1 segundo). (No tengo forma de determinar los segundos exactos)
Tenga en cuenta: el hecho de que las directivas no se evalúen es una suposición fundamentada sobre lo que está sucediendo debajo.
Entonces, 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, utilice ng-if.