1

I have an element(a sidebar) where I only want to show it when the user is authenticated. This sidebar has some javascript actions, like expanding/contracting toggler. When I use ng-show, it works fine, but when I use ng-if it just stops working. Does anyone know why it happens? I don't have problem rendering it. The problem is some jquery scripts don't work while using ng-if. I know the difference between ng-if and ng-show, where ng-if creates a new DOM, scope and all, while ng-show just hides the element with CSS.

<div ng-if="sidebar && signedUser" ng-cloak>

    (some components here...)

    <ul class="navbar-nav sidenav-toggler">
      <li class="nav-item">
        <a class="nav-link text-center" id="sidenavToggler">
          <i class="fa fa-fw fa-angle-left"></i>
        </a>
      </li>
    </ul>
</div>

Expanded sidebar (using ng-if the toggler doesn't work)

Using ng-show I can contract it

  • 2
    Ng-show renders the dom but keeps it hidden, ng-if doesnt render at all if false – dark_ruby May 01 '18 at 14:35
  • 2
    `ng-if` has its own scope and deletes DOM (as well as scoped watchers), while `ng-show` is just some CSS magic that only hides your content – Aleksey Solovey May 01 '18 at 14:36
  • 1
    you could try to reach the controller's scope with `ng-if="$parent.some_variable"` syntax. Additionally, you [shouldn't use jQuery with angularjs](https://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background), it's not part of the digest cycle. If you have issues with bootstrap functionalities, try angularjs version - [`ui.bootstrap`](https://angular-ui.github.io/bootstrap/) – Aleksey Solovey May 01 '18 at 15:08
  • @AlekseySolovey I'll try this out! Didn't know this 'incompatibility' between jQuery and AngularJS. Thanks a lot! – Matheus Medeiros May 01 '18 at 15:16
  • 1
    @MatheusMedeiros in short: jQuery manipulates DOM, while AngularJS renders it. You can't manipulate something that hasn't been rendered yet, which happens during digest cycles after any watchers were changed (two-way data-binding like `ng-model` or `{{ }}`). If you want to manipulate DOM, use AngularJS **directives**, they have jQLite – Aleksey Solovey May 01 '18 at 15:19
  • @dark_ruby That's not entirely true - `ng-if` **removes** the element if the expression evaluates to false. The element will be rendered prior to `ng-if` being evaluated. This is important to understand since there may be side-effects of rendering an element (even if only for a very brief time) if you expect the element to never be there under certain conditions when using `ng-if`. – Lex May 01 '18 at 16:12
  • @lex ofcourse it will render it first – dark_ruby May 01 '18 at 19:26

1 Answers1

3

As others stated in the comment above,

ng-if will remove elements from DOM which means all your handlers or anything else attached to those elements will be lost.

ng-show/ng-hide does not remove the elements from DOM. It internally uses styles to hide/show elements

Sajeetharan
  • 216,225
  • 63
  • 350
  • 396