There’s a critical and undocumented (AFAIK) distinction between several of Angular’s directives. On the surface, ng-show/ng-hide, ng-switch and the new ng-if all produce exactly the same results: partials/DOM-fragments that appear and disappear. I used to think that ng-Show and ng-Switch were just different syntax for the same thing: convenience variations, essentially. And then, ng-If came along for Angular 1.2, which made me scratch my head and take another look.
Turns out the apparent similarities in outcome are deceptive, and mask fundamentally different implementations: ng-show & ng-hide simply toggle the visibility of an element or DOM fragment that’s already in the DOM, while ng-switch and ng-If actually detach and reattach the elements/fragments/templates from the DOM. (Note that Angular 1.0.8 and 1.2 do this in different ways. The 1.2 implementation is far preferable. Comparative implementations are linked from the relevant code below.)
This has significant implications for performance, for how you construct your CSS selectors, and much else.
I built a CodePen to demonstrate the differences between these directives, and added a separate Plunker (linked from the CodePen) to show how Angular 1.08 did ng-Switch differently than 1.2. Use your inspector to see what’s going on under the hood. I’d embed said Codepen, if only WordPress.com was a little more flexible…
Reblogged this on Sahara Hacker.
This part nailed it: “ng-show & ng-hide simply toggle the visibility of an element or DOM fragment that’s already in the DOM, while ng-switch and ng-If actually detach and reattach the elements/fragments/templates from the DOM.”
Thanks UI guy.
Quick question: Is ng-if and ng-switch ‘better’ than the other two? If so, why would you use the other two?
Sometimes, you want to keep the content ‘active’, so that you can continue updating it, and reacting to it. It also keeps you from needing to recompile it each time you show it. Put another way: I’d lean towards using ng-show/hide for dynamic content that user interaction is going to toggle in and out of visibility. In contrast to that concern, ng-if would be great for content that’s only going to show at all under certain circumstances, but isn’t going to be toggled after the decision is made.
Multi-page forms are a good case for ng-show. You might use ng-form to break a single logical form up into multiple user views, and you only want to show one of those pages at a time. So the content itself is hidden. But you want to maintain a validation process that’s operative on the whole form, which means keeping it all in-scope on the javascript side at all times. If you use ng-if, the hidden parts of the form will actually wink out of existence, and so you lose their form-controllers and input-controllers. In that case, you’re more concerned about maintaining the javascript objects that are linked to the piece of DOM, than you are about where the DOM objects themselves are.
Hello XmLilley, does that mean when I would use ng-switch for a multi-page form (wizard) and switch the single pages I loose the UI State? And with ng-show not?
I believe so, because the ngInput controllers will be destroyed when you transition. If you’re using angular validations, then all the validation statuses are lost. Each time you revisit a page of the form, its values will once again be $pristine and $untouched.