Being notified when an AngularJS Directive is hidden/shown? - angularjs

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.

Related

Angularjs hide DOM elements but still draw them so directive events fire?

I'm using ngHandsontable in an angular ui-router app. My table take 1-2 seconds to render (10x20 cells, which isnt create but fine ...).
The issue is that I cant use angular ng-if or ng-show to hide the table and show a loading template until the afterRender events fire because if I hide the hot-table dir like that, then the DOM is never drawn and obviously the afterRender event wont fire.
Any suggestions how to show a loading template while table is rendering? I'm thinking maybe an overlay? Is there an angular directive that will hide the DOM element but still insert/draw it?
<hot-table></hot-table>

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

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

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

How can I tell Angular not to compile child nodes when using $compile

The situation is I have an HTML structure somewhat similar to this:
<div class="dynamicDirectiveGoesHere">
<p>{{SomeExpressionThatDiffers}}</p>
</div>
I need to display a bootstrap http://angular-ui.github.io/bootstrap/ popover when the text within p has an ellipsis. That's why I'm adding the popover attribute dynamically. I can get the popover to display using $compile, but the problem is the text within {{ }} goes away. I can't use the template trick since I don't really know what the template will be since the popover will happen on several different child tags that have different templates. So that's why there is the need to only $compile what's in div, and not in the child element (p tag). Is this possible with angular?
You can add the property terminal to your directive and adjust the priority to fit your needs.
terminal: true prevents other directives from getting instantiated and is used by for example the ng-repeat and ng-if directive.
You can read more here https://docs.angularjs.org/api/ng/service/$compile (scroll down to terminal).

angular how to not render element content?

there is an ng-show directive in angular, but is there a ng-render directive? that adds the template of a directive to the dom only when conditions are met?
the problem with ng-show is that it only uses css to hide elements, and since I am creating an enormous list, and I am only displaying the visble elements, I dont want the content of not visible content to be partially rendered.
You can use ng-if or ng-switch. Neither include content unless your conditions are met.

Resources