ng-repeat and ui-if - angularjs

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.

Related

display current value of ng-class in AngularJS

I have to track down a bug related to work of ng-class (sometimes it adds new value without removing old).
So I need a quick reference to see it's current value.
Is there any short (or not) way to bind that to the content?
I mean something like this:
<div ng-class="something">
{{ngClassValueDisplayedHere}}
</div>
I had exactly the same problem with ng-class not removing old value. After days of investigation it turned out that it was ngAnimate who was messing with class changes. removing it from angular module dependencies solved the problem (Angular 1.3).
ng-class can bind to many different things. From the documentation:
Expression to eval. The result of the evaluation can be a string representing
space delimited class names, an array, or a map of class names to boolean
values. In the case of a map, the names of the properties whose values
are truthy will be added as css classes to the element.
So in your example, just display whatever your something is. It's supposed to be an angular expression, which can be evaluated like any other with double-curlies. This will help you debug your ng-class
<div ng-class="something">
{{something}}
</div>
Demo
In case someone else stumbles upon this problem like I did just recently with angular version 1.5.8: https://github.com/angular/angular.js/issues/14582
P.S. Update to 1.5.11 solved the issue related to ngAnimate, prior versions still had the same issue.

How to optimize ng-switch

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

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>!

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>

Conditional outer tag in a directive (i.e. <strong>)

I like a directive that conditionally puts a tag outside some content (but always prints the content), like this:
<p><strong ng-if-always-keep-inner-content="model.condition">{{model.text}}</strong>/p>
so if condition is true I get
<p><strong>yada yada</strong></p>
otherwise I get
<p>yada yada</p>
I could write it myself, but I want to know if it is possible to do with built in directives/options.
I should perhaps say this is used together with Bootstrap, which afaiu recommends using <strong> vs some class with a bold font.
I don't think there is a built in directive. You should write it.
I suggest to use a classic ng-if
<p ng-if="model.condition"><strong>{{model.text}}</strong></p>
<p ng-if="!model.condition">{{model.text}}</p>
In your specific case, you can also use ng-class and set the strong style via css.

Resources