You’re moving your pages from AngularJS to Angular… but you’ve got a bunch of pesky elements flagged with ng-show and/or ng-hide. Here’s how to migrate to (mostly) the same functionality in Angular.
You’re moving your pages from AngularJS to Angular … but you’ve got a bunch of pesky elements flagged with ng-show and/or ng-hide. Here’s how to migrate to (mostly) the same functionality in Angular. In fact, here are two solutions.
In Angular you were controlling the display of content on your page with ng-hide with markup like this:
<span ng-show="bolShow">…content to display and hide…</span>
If you’re moving to Angular, then you’ve discovered that ng-show and ng-hide don’t exist anymore. The short answer to this problem (though not the most reliable) is to switch to using the HTML5 hidden attribute. As an example, this code binds the field bolShow to the hidden attribute and then uses the attribute to control whether a span element’s content is displayed:
<span [hidden]=”!bolShow”>…content to display and hide…</span>
Using hidden also works if you’re using ng-hide. If you had:
<span ng-hide="bolHide">…content to display and hide…</span>
then you could replace it with:
<span [hidden]=”!bolHide”>…content to display and hide…</span>
There are some usage notes here:
- The square brackets around the hidden attribute ensure that the attribute is set to the value in bolShow (and isn’t set to the string “!bolShow”).
- The variable you’re using (bolShow, in my example) needs to be set to values you’re sure are truthy and falsy.
For that last issue, the values true and false are your best choices, of course. If you set hidden to the strings “true” or “false”, for example, because those values are string, they’re always truthy and the span tag’s content will always be visible.
What this solution does is cause the hidden attribute to be added to the span element when bolShow is false and be skipped when bolShow is set to false. Interestingly, under the hood, both ng-hide and ng-show were applying CSS style rules to control whether the content was displayed. Effectively, with this solution, you’re managing the HTML yourself and eliminating CSS … possibly.
The problem with using the hidden attribute, though, is that the attribute has a lower priority than CSS rules. As a result, if there’s a CSS style rule assigned to your element that causes the element to appear, then it doesn’t matter what you set the hidden attribute to. A rule that, for example, sets the CSS display property to anything but none will cause your content to display; if display is set to none, then it doesn’t matter what you set hidden to.
If you want the hidden attribute to work every time, then, in the stylesheet used by the page, you can add the CSS important rule to the hidden attribute, like this:
display: none !important;
With the important rule added onto the hidden attribute, the hidden attribute overrides any CSS rules applied to the element—you’ll always get the result you expect (for the record, this is the way the style rules that ng-show and ng-hide used were configured).
If you’re going to use CSS style rules, you might want to consider using CSS’s visibility property instead of hidden. Visibility lets you control how much space a hidden element takes up. When the element is hidden, visibility:none gives up the space the element would normally occupy. On the other hand, with visibility:hidden, the element continues to occupy its space, though without displaying its content.
An Alternative Solution
But this is starting to get ugly. Using important is considered a bad practice in CSS precisely because it does upend the styling priority system (CSS is called “cascading” for a reason). Furthermore, you’re now involved with both the hidden attribute on your elements and a special rule in your stylesheet.
For both these reasons, the *ngIf directive might be a better choice. Unlike using the hidden attribute, *ngIf works its magic independently of CSS. In this example, if bolShow is true then the span tag’s content will be rendered, no matter what CSS rules are involved:
<span *ngIf=”bolShow”>…content to display and hide…</span>
What can I say? There is no perfect solution. But you do get to pick whether you’ll have your arm cut off or ripped off.