Angular’s ng-Show vs ng-Switch (and ng-If!): Important Differences

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…

Angular 1.2 CodePen

Advertisements

6 thoughts on “Angular’s ng-Show vs ng-Switch (and ng-If!): Important Differences

  1. Sam says:

    Reblogged this on Sahara Hacker.

  2. amigotips says:

    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.

  3. amigotips says:

    Quick question: Is ng-if and ng-switch ‘better’ than the other two? If so, why would you use the other two?

    • XMLilley says:

      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.

  4. bastien says:

    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?

    • XMLilley says:

      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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: