In my AngularJS I have the following code where I check if there is a currently logged in user or not in order to switch the top app menu text from Login to Logout (login if no user is logged in) and vice versa. When I used ng-show ng-hide the app started to be extremely heavy so I tried switching to ng-if, but then the css effects on the top menu started not to work specifically in the login/ logout tab. So can someone please tell me what is the best approach to handle this situation with example please? Thanks
index.html
<div ng-controller="MenuController">
<li>
<div ng-if="userLevel() == 1">
Login
</div>
<div ng-if="userLevel() == 2">
Logout
</div>
</li>
</ul>
</div>
Controller:
controller('MenuController',
function MenuController($scope, UService){
$scope.userLevel = function(){
var userType = UService.checkULevel(); //This will return either 1, 2,3,4...etc
return userType;
};
});
The difference between ng-show and ng-if is that ng-show applies a display: none to the element when the specified expression is a false value, while the ng-if removes the node from the DOM, basically equivalent to the .empty in jQuery.
An approach you can consider for your element, is rather than using it within a controller, use a directive for the access level, and follow the approach described in this article, which is really flexible and allows you to have different elements in the UI depending on the user level: http://frederiknakstad.com/2013/01/21/authentication-in-single-page-applications-with-angular-js/
Another reason for your application to be slow when you check the user level, could be that every time that is evaluated your application has to perform a check on the server side, slowing the application. An approach for it would be to cache the result of that query, and then use it while the login status doesnt change. At that stage you can invalidate the cache and fetch the user level again, ready to update the UI.
The ng-if directive removes the content from the page and ng-show/ng-hide uses the CSS display property to hide content.
I am pretty sure that no-show is lighter than ng-if and no-show should not make the app too heavy. If it is becoming heavy, I think there could be other causes for it.
If you use ng-if the node is rendered only when the condition is true
In case of ng-show ng-hide the Nodes will be rendered but shown/hidden based on the condition if condition changes the same nodes are shown/hidden
when ever you use ng-if it will render only that code which satisfy the condition.
while ng-show ng-hide will render the code on page but will be hidden with the help of CSS properties.
so better to use ng-if for reducing the line of code to be rendered on page.
Related
I have an ng-include directive inside a section which needs to conditionally hide the data being shown from ng-include url. If i hide section, I never get the ng-include data but if i start with visible section every thing works. here is some ex :
if condition: true;
<section ng-show="condition">
<div ng-include='url'>
</section>
Everything works as expected.
however if i first start with condition: false; i never see data from ng-include even when i set condition to true (via event)
What's wrong here ?
I believe you should use ng-if instead. As per my understanding the DOM is not reproduced on show hide, but when we use ng-if, DOM changes in the sense that element gets removed from DOM and injected back based on condition is false or true.
When I click an element, I'd like another element to first fade out, and then be set to display: none.
I have the following code:
Partial:
<div class="main_menu_image" ng-class="{ fadeOut : MenuOpen==true }" /></div>
<div class="button" ng-click="ActivateMenu()"></div>
Then in my controller:
$scope.MenuOpen = false;
$scope.ActivateMenu = function(){
$scope.MenuOpen = $scope.MenuOpen === false ? true: false;
}
So when I click the button, element main_menu_image gets the class fadeOut. So it now fades out. But after the fading animation completes I would also like to set display to none on main_menu_image so it is completely hidden.
I don't want to resort to jQuery. Is there an Angular approved way of doing this?
Yes it's very easy to do:)
Like Svein says, you can use ng-show, and you can use ng-hide.
Working fiddle here
This hides things instantly though. But you can for example set a timeout, via the $timeout service, and set your hiding boolean in that way.
You can also use ng-if, this actually removes the element from the DOM if the condition is not met, rather than just setting display:none.
Update: Here's a more proper fiddle showcasing what you're trying to do
You can use ngShow. If you use the ngAnimate module, you'll have built in support for animations for most built-in Angular directives.
See here for more information:
https://docs.angularjs.org/guide/animations
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>
I'm using Angular JS and Angular IU-Router in my project and using a lot of ui-views. I have a situation where I need to change the language of the site, therefore I need to swap my ui-view's model to another model with the relevant language. I already have a service that detects the relevant model and passes it into the ui-view's controller. So if I can reload the ui-view, then in theory my problem would be solved.
I recall reading something about automatically reloading a ui-view (or possibly an ng-view) and re-instantiating its controller, but after much searching I haven't been able to find that information again.
Does anyone know what it is I'm looking for?
1 Take a look at angular-translate
https://github.com/PascalPrecht/angular-translate
2 In your case, add some if-else control ( ng-if, ng-switch etc. ) in the outer div, use the same subview in the inner div. Then change the settings.currentLang when the language changes may cause the subview reload (not tested).
<div ng-controller="containerCtrl">
<div ng-if="settings.currentLang=='en'">
<div ui-view='subview'></div>
</div>
<div ng-if="settings.currentLang=='ja'">
<div ui-view='subview'></div>
</div>
</div>
I have been working with routing and I have seen how I can update the ng-view using routing and a view template.. But the problem I have is that I am doing a REST call and depending what I get back from the response I wish to update part of the DOM with a view template but I don't want to involve routing.
Does anyone know how I can do this? Or any examples would be great
Thanks in advance
Another answer. Based on your description in the comment, it sounds like you wish to display part of the DOM conditionally.
When you want to display part of the DOM conditionally, you have the following choices:
Use an ng-show and ng-hide directive.
Based on what returns from the RESTful call, you can set up a model that will identify the DOM that needs to be displayed. An example:
<div ng-show="status">
This text will be shown only when the status is truthy
</div>
<div ng-hide="status">
This text will be shown only when the status is false.
</div>
Inside your controller, you could then set the status to true or false based on your RESTful calls and based on which part of the DOM you wish to display post RESTful call.
You can use ng-switch directive
While the ng-show and ng-hide directives will display the content of your DOM conditionally, that is anybody could simply open the source file and see the contents for both, ng-switch directive will load the contents only based on which case fulfills the swtich. An example:
<div ng-switch on="status">
<div ng-switch-when="true">
This text will be shown only when the status is truthy.
Else this is completely hidden and cannot be seen even
when looking at the source.
</div>
<div ng-switch-when="false">
This text will be shown only when the status is false.
Else this is completely hidden and cannot be seen even
when looking at the source.
</div>
</div>
The first child div is shown when the status is true else it is not shown at all. The advantage over ng-show or ng-hide is that the DOM will not contain the child elements if the case is not fulfilled.
$location.path() can be used here.
So, in your Parent Controller, you can make the REST call. Once you have the data with you, you can then decide which route to take. The route value goes into the path() function.
As an example, let us say that if your REST call returns with cherries, you need to take the /foo path (which, based on your $routeProvider will load the template associated with that route). You can then write the following:
$location.path('/foo');
and it will loads the /foo path - $routeProvider will then take care of loading the template associated with that path.
Reference: $location