How to optimize ng-switch - angularjs

I'm using angular's ng-switch to build form's fields like this
<div ng-switch="vm.myField">
<my-input-type1 ng-switch-when="type1"></my-input-type1>
<my-input-type2 ng-switch-when="type2"></my-input-type2>
<my-input-type3 ng-switch-when="type3"></my-input-type3>
<my-input-type4 ng-switch-when="type4"></my-input-type4>
<my-input-type5 ng-switch-when="type5"></my-input-type5>
<my-input-type6 ng-switch-when="type6"></my-input-type6>
<my-input-type7 ng-switch-when="type7"></my-input-type7>
<my-input-type8 ng-switch-when="type8"></my-input-type8>
</div>
because of performance it's not good solution (on entering view with it brwser is pausing for a while).
Without ng-switch all is rather ok.
How can I optimize it? ng-if has the same prefomrance issue.

As you probably know from the Angular documentation (https://docs.angularjs.org/api/ng/directive/ngSwitch)
ng-switch works by adding and removing the nested DOM element based on a conditional statement. This can be quite slow for large templates/DOM elements.
One solution I used was to use ng-show/ng-hide (https://docs.angularjs.org/api/ng/directive/ngShow).
These directives do not modify the DOM structure, but instead use CSS to hide/show the elements. It can be faster, but beware that the DOM could become very large if you fall into the trap of trying to contain all of templates/DOM elements of your web site in memory at the same time in this manner.

I think I found a solution.
Insead of ng-switch I'm using
<ng-include src="'/my-fields/directives/'+vm.myField+'.html'"></ng-include> with proper html code.
For now works good but have to test a bit more.
EDIT: now it is much, much faster

Related

Smart admin with ng-repeat

I am using angularjs from 2 months but never comes to problem like this, so thought of sharing with you people and getting some good suggestion on that. Here I am trying to apply ul/nav-group element dynamic values. Everything is working fine means, if I see developer tools on browser it gets value and everything, but not the +/- sign. I search on google its saying that it loads after DOM creation so it is not showing that. But no buddy tells the solution for that.
Consider my code:
<nav:group ng-repeat="parentChild in parentChildList" title="{{parentChild.filterText}}">
<nav:item data-view="/ui/icons/fa" ng-repeat="childs in parentChild.childList" data-icon="fa fa-lg fa-fw fa-plane" title="{{childs.filterText}}" />
</nav:group>
The value for particular fields are straight forward means its simple list.How the directive can solve this problem.
Appreciate any suggestions . Thanks.
Add an ng-cloak directive on the body tag of your app to prevent loading the element until angular has finished loading.
Your body tag would look like this:
<body ng-cloak>
...
</body>
You could also fix this by using promises in your services, that is definitely the best practice regardless, but ng-cloak is a quick and easy fix.
Hope that helps! If ng-cloak doesnt work for you post snippets of your controller and service and I will help you add promises.
Good Luck!
-Justin

Angularjs : Display accolades {{ }} several milliseconds before rendering

I am going to create an application with Angularjs. I have several modals (with the ng-dialog libraries) to create, modify data like an user for example.
When I open it, I can always see during several milliseconds names variables with accolades like {{user.name}}, before it renders the real value.
It is not really beautiful and then if someone has an idea about how to manage this type of display problems, please share it.
Thank you in advance.
There are couple of ways to deal with it, you could either use ng-bind or ng-cloak directives
Check angular ngCloak directive documentation
https://docs.angularjs.org/api/ng/directive/ngCloak
You can use ng-bind. Here is the official documentation on it:
It is preferable to use ngBind instead of {{ expression }} if a template is momentarily displayed >by the browser in its raw state before Angular compiles it. Since ngBind is an element attribute, >it makes the bindings invisible to the user while the page is loading
Usage:
Hello <span ng-bind="name"></span>!

ng-style or style attribute with binding? Which is better? Which is faster? What is the difference?

I am optimizing my large application. I am confused between following two approach, please help to decide which one is faster.
Inline style attributes
<div style="background-color:{{item.color}}"></div>
Using ng-style
<div ng-style="{'background-color':item.color}"></div>
Using once-style
<div once-style="{'background-color':item.color}"></div>
Note : For once-style, I have used AngularOnce Directive.
Thanks in advance. Please tell me which one is faster and why.
One time bind is available after Angular 1.3.
You can do this way without depending on third-party libraries:
<div ng-style="::{'background-color': item.color}"></div>
I didn't measure the performance, but I'm pretty sure that its better than without the colons.
Since you are optimizing your considerably large application, performance is definitely under question and I think ngStyle performs better as it sets up watch on the model and will update the view only if the model has changed.
So I would go with ngStyle or onceStyle depending on your scenario:
<div once-style="{'background-color':item.color}"></div>
Using {{}} will make Angular update the binding every digest cycle, even if the value has not changed.

Hide Angular brackets until javascript loaded

I have a few bits of HTML like
<p class="noresults">{{numberOfContacts}} Results Are Available</p>
Is it possible for me to hide {{numberOfContacts}} until Angular has loaded? So it would just say Results Are Available
I've seem some solutions such as hiding the entire body until Angular has loaded, but I'd rather not do that if possible.
Yes, use ng-cloak. Simply add class="ng-cloak" or ng-cloak to an element like this
Using directive <div ng-cloak></div>
Using class <div class="ng-cloak"></div>
It's simply a set of CSS rules with display: none !important and as Angular has rendered your DOM it removes the ng-cloak so an element is visible.
use <span ng-bind="numberOfContacts" /> instead of {{numberOfContacts}}
Sometimes, even if I used the ng-cloak, I could still see the braces for a few seconds. Adding the following style resolved my issue:
[ng-cloak]
{
display: none !important;
}
Please see this link link for more explanation.
Hope it helps :D
This is typically only an issue when working with complex content on really slow devices. In those instances, there can be a brief moment when the browser displays the HTML in the document while AngularJS is parsing the HTML, getting ready, and processing the directives. In this interval of time, any inline template expressions you have defined will be visible to the user. Most devices nowadays have pretty good browsers which are quick enough to prevent this from being an issue. There are two ways to solve the problem.
Avoid using inline template expressions and stick with ng-bind directive.
(Best) Use the ng-cloak directive which will hide the content until Angular has finished processing it. Basically, the ng-cloak directive uses CSS to hide the elements and angular removes the CSS class when the content has been processed, ensuring that the user never sees the {{ and }} characters of a template expression.
One strategy to consider is using the ng-cloak directly to the body element, which will ensure that the user will see an empty browser while AngularJS loads. However, you can be more specific by applying it to parts of the document where there are inline expressions.
I have seen issues with ng-cloak not working when added to an element. In the past, I have worked around this issue by simply adding ng-cloak class to element.
You can use ng-bind instead of expression like
<span ng-bind="data"></span>

ng-repeat and ui-if

When I want to use ui-if (anguluarUi) with ng-repeat (and I think it would be most useful there) I Get an error:
Error: Multiple directives [uiIf, ngRepeat] asking for transclusion on: <!-- uiIf: oConnection.aOptions -->
Is there any way to combine those two?
Edit:
<ng-repeat><div ui-if>...
Is not possible (for now) unfortunately.
I know that I can combine ng-show and ng-repeat, but it's not the same.
I also don't want to put the ui-if outside of the repeat, as I want to use the values of the repeat for the condition.
I think that a filter should be used instead of ui-if.
ui-if was removed at least from latest version angular-ui but since angular 1.1.5 you have ng-if build-in.

Resources