angular - directive on an element under ng-if not working - angularjs

I have a page with tabs, here's an example of one of them:
<li ng-if="userData.isMaster">
<a data-target="#debug-tab" data-toggle="tab" data-tab-name="debug" on-tab-shown>Debug</a>
</li>
This tab is similar to other tabs, with the exception that it is under ng-if. Each tab has an "on-tab-shown" directive which broadcasts an event each time the tab is shown. Inside each tab's controller there's an event listener that listens to this event. In other tabs, that are not under ng-if, the event is received by the listeners, but not in this tab. It is possible to replace the ng-if with ng-show to make it work, but are there better ways maybe?

If your ng-if is set to not show the tab (userData.isMaster == false), then the tab is removed from the DOM. Since it isn't on the DOM, it won't react to the broadcast. If you need it to react to the broadcast even though it isn't showing, you will need to use ng-show so it is simply hidden.

I'm afraid no. The thing is, that ng-if completely blocks the linking of the element it's put on and all its children (in fact, they're even removed from the DOM). That's why ng-show works, because ng-show does not block any linking.

There's no reason not to favor ng-show if it works better. All you're doing is adding to the DOM, or not. Per Angular's documentation:
ngIf differs from ngShow and ngHide in that ngIf completely removes and recreates the element in the DOM rather than changing its visibility via the display css property.
Here's the link if you'd like more info -- good luck!!
https://docs.angularjs.org/api/ng/directive/ngIf

Related

AngularJS ng-if and DOM Compilation

I am using a datepicker control on my page which is rendered through ng-if dependent on a specific dropdown value.
The problem I'm facing is since at the time of rendering, that datepicker input is not part of DOM, so later when I change the value of dropdown, the datepicker control does not work.
If I use ng-show, I encounter issues in validations.
Any suggestions?
Thanks.
Use ng-show/ng-hide instead of ng-if, because the ng-if directive removes or recreates a portion of the DOM tree based on an expression. If the expression assigned to ng-if evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.
More details. please refer this link : what is the difference between ng-if and ng-show/ng-hide
Try "$scope.apply()" after the toggling of ng-if variable.

ng-if or ng-show to hide and show a DIV?

The code I am working on has this:
<div ng-if="cos.connectMessage" style="text-align: center;" class="ng-scope">
Unable to establish a connection to the localhost server for 5 minutes.</div>
Is there any advantage to using ng-show or ng-if to control the visibility of this message?
ng-show
The ngShow directive shows or hides the given HTML element based on the expression provided to the ngShow attribute. The element is shown or hidden by removing or adding the .ng-hide CSS class onto the element. (reference)
ng-if
The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM. (reference)
Note: When ng-if removes the element it also removes the associated scope for that element and it get recreated when condition turns true.
Advantage
I prefer the use of ng-if specifically when number of watchers bound inside the element is more as it would completely destroy the scope so making the UI a bit faster. But for small elements or elements containing less watchers does cost overhead of removing scope and recreating it.
You can refer this for your solution, already lot of things asked in that
what is the difference between ng-if and ng-show/ng-hide
If you are using ng-if="false" then html content under ng-if will not includ in your html page, but if you are using ng-hide="true" or ng-show="false" then html part includ in your html page but it will only in hidden mode.

When to use ng-if vs ng-show/ng-hide?

I understand that ng-show and ng-hide affect the class set on an element and that ng-if controls whether an element is rendered as part of the DOM
Are there any examples on choosing ng-if over ng-show/ng-hide or vice-versa?
You've already summed it up in your question. If you want to show and hide the DOM depending on a condition, use ng-show. This works well for DOM transitions between workflows, tabs, sections, etc.
<div ng-show="vm.tab == 'products'"></div>
If you only want to conditionally render the DOM if a condition occurs, use ng-if. This is particularly useful for permissions where you aren't interested in exposing any more DOM than necessary.
<button ng-if="vm.data.allowSubmit" ng-click="vm.submit()" />
If there is some information what you dont want to show to user any how.
You want that user cant see it anyhow even after editing DOM from inspect element then use ng-if otherwise use ng-show.
ng-show renders the dom but if condition is false then element display will be invisible.
`ng-if` renders the `dom` only if condition is true
There are situations when you are force to use ng-show
ex: Consider you are using any jquery plugin which runs on dom ready on any element. If element is getting rendered later when ng-if gets true then jquery will not work. In this case you will be need to use ng-show

ng-if is not working as expected

I'm trying to use ng-if to show and hide some data based on tabs because I don't want all the html to be on the DOM all the time. Here's what I'm trying to do. It seems the ng-if is working only when the page is loaded, after that on the click of the sub tabs, it's still updating the scope variable, but I don't see the change on the UI. Please help.
Thanks.
Remove ng-href="#" from your links. This is all you need:
<li ng-repeat="subTab in tabData.SubTabs">
<a ng-click="subTabClicked(subTab)">{{subTab.Name}}</a>
</li>
With ng-href present, currentTabId is being updated on a child scope for each tab. On the parent scope, where ng-if is watching, currentTabId was never changed.
Here is a demo: http://plnkr.co/ISwjaWKggdbGL38BW078

Being notified when an AngularJS Directive is hidden/shown?

I have a custom directive that has to be hidden when my page loads, but later if the user clicks something it shows the directive. However, the ng-hide is placed on a parent node outside the dom node the directive lives on. This directive needs to run some code to place its components, but it has to run it when the parent dom node is shown. How can I get notified the dom has changed and the directive is now being shown so I can run my code to calculate the size?
If I don't hide the directive everything works great. However, if I hide it. It fails to render properly.
So, while ng-show or ng-hide are ok for simple DOM elements, sometimes it's better to use ng-if and basically delay the rendering until the show condition has been met. This will in most cases avoid bad renders that can happen when things are rendering in the background using ng-hide or ng-show.
ng-if was introduced in 1.1.5 and it's basically a simplified ng-switch. It was inspired by Angular-UI's ui-if.

Resources