I'm trying to understand the difference between ng-if
and ng-show
/ng-hide
, but they look the same to me.
Is there a difference that I should keep in mind choosing to use one or the other ?
I'm trying to understand the difference between ng-if
and ng-show
/ng-hide
, but they look the same to me.
Is there a difference that I should keep in mind choosing to use one or the other ?
Maybe an interesting point to make, is the difference between priorities between both.
As far as I can tell, the ng-if directive has one of the highest (if not the highest) priority of all Angular directives. Which means: it will run FIRST before all other, lower prioritised, directives. The fact that it runs FIRST, means that effectively, the element is removed before any inner directives are processed. Or at least: that's what I make of it.
I observerd and used this in the UI I'm building for my current customer. The entire UI is quite heavily packed, and it had ng-show and ng-hide all over it. Not to go into too much detail, but I built a generic component, which could be managed using JSON config, so I had to do some switching inside the template. There is an ng-repeat present, and inside the ng-repeat, a table is shown, which has a lot of ng-shows, ng-hides and even ng-switches present. They wanted to show at least 50 repeats in the list, which would result in more or less 1500-2000 directives to be resolved. I checked the code, and the Java backend + custom JS on the front would take about 150ms to process the data, and then Angular would chew some 2-3 seconds on it, before displaying. The customer did not complain, but I was appalled :-)
In my search, I stumbled across the ng-if directive. Now, maybe it's best to point out that at the point of conceiving this UI, there was no ng-if available. Because the ng-show and ng-hide had functions in them, which returned booleans, I could easily replace them all with ng-if. By doing so, all inner directives seemed to be no longer evaluated. That meant that I dropped back to about a third of all directives being evaluated, and thus, the UI speeded up to about 500ms - 1 sec loading time. (I have no way to determine exact seconds)
Do note: the fact that the directives are not evaluated, is an educated guess about what is happening underneath.
So, in my opinion: if you need the element to be present on the page (ie: for checking the element, or whatever), but simply be hidden, use ng-show/ng-hide. In all other cases, use ng-if.
ng-show and ng-hide work in opposite way. But the difference between ng-hide or ng-show with ng-if is,if we use ng-if then element will created in the dom but with ng-hide/ng-show element will be hidden completely.
One important thing to note about ng-if and ng-show is that when using form controls it is better to use
ng-if
because it completely removes the element from the dom.This difference is important because if you create an input field with
required="true"
and then setng-show="false"
to hide it, Chrome will throw the following error when the user tries to submit the form:The reason being the input field is present and it is
required
but since it is hidden Chrome cannot focus on it. This can literally break your code as this error halts script execution. So be careful!One interesting difference in ng-if and ng-show is:
SECURITY
DOM elements present in ng-if block will not be rendered in case of its value as false
where as in case of ng-show, the user can open your Inspect Element Window and set its value to TRUE.
And with a whoop, whole contents that was meant to be hidden gets displayed, which is a security breach. :)
To note, a thing that happened to me now: ng-show does hide the content via css, yes, but it resulted in strange glitches in div's supposed to be buttons.
I had a card with two buttons on the bottom and depending on the actual state one is exchanged with an third, example edit button with new entry. Using ng-show=false to hide the left one(present first in the file) it happened that the following button ended up with the right border outside of the card. ng-if fixes that by not including the code at all. (Just checked here if there are some hidden surprises using ng-if instead of ng-show)
ngIf
The
ngIf
directive removes or recreates a portion of the DOM tree based on an expression. If the expression assigned tongIf
evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.When an element is removed using
ngIf
its scope is destroyed and a new scope is created when the element is restored. The scope created withinngIf
inherits from its parent scope using prototypal inheritance.If
ngModel
is used withinngIf
to bind to a JavaScript primitive defined in the parent scope, any modifications made to the variable within the child scope will not affect the value in the parent scope, e.g.To get around this situation and update the model in the parent scope from inside the child scope, use an object:
Or,
$parent
variable to reference the parent scope object:ngShow
The
ngShow
directive shows or hides the given HTML element based on the expression provided to thengShow
attribute. The element is shown or hidden by removing or adding theng-hide
CSS class onto the element. The.ng-hide
CSS class is predefined in AngularJS and sets the display style to none (using an!important
flag).When the
ngShow
expression evaluates tofalse
then theng-hide
CSS class is added to theclass
attribute on the element causing it to become hidden. Whentrue
, theng-hide
CSS class is removed from the element causing the element not to appear hidden.