AngularJS - Handle repeated fragments like Header and Footer - javascript

I have been trying to implement the header / footer in an Angular JS App. I was thinking of adding these as ng-include in the main index.html. However this would have worked if the header and footer are static pages. My case is slightly different... In Login page no header / footer is shown. Other pages depending on whether you are logged in or not, you have to show "Welcome user [ logout] " or "Welcome guest [ login ]".
I save the login information in the rootScope as well as set a boolean $rootScope.isLoggedIn on login. The biggest problem seems to be that the whole ng-include is not refreshed on a logoff. Hence divs with ng-show hide directives will not hide/show on change. Somebody suggested using ng-switch - it also behaves the same way.
If I move the header code inside individual views then everything is fine.
A similar question is here: Refresh header page in angularjs

Use a controller in the header/footer, as ivarni suggested. An example from an (experimental) app of my own:
In the index.html, the header will display a dynamically generated menu, login/logout etc:
<div id="navbar" class="navbar navbar-inverse navbar-fixed-top"
x-ng-controller="NavbarCtrl" x-ng-include="'app/main/navbar.html'"></div>
The NavbarCtrl builds the appropriate scope for the app/main/navbar.html template. The template would be as follows (taking into account your needs - and irrelevant details removed):
<div class="navbar-inner" x-ng-if="showHeader">
<div class="container">
<div>
<ul class="nav">
<li x-ng-repeat="menuEntry in menuEntries">
<a x-ng-href="#{{menuEntry.path}}">{{menuEntry.display}}</a>
</li>
</ul>
</div>
</div>
<div x-ng-if="userData.loggedIn">
Wellcome {{userData.userName}}!
<a x-ng-click="logout()">Logout</a>
</div>
<div x-ng-if="!userData.loggedIn">
<a x-ng-click="login()">Login</a>
</div>
</div>
So the entire markup is hidden depending on the showHeader scope variable. It creates the menu dynamically (menuEntries). And depending on userData.loggedIn, the appropriate Login/Logout message.

Related

Unable to scroll to a div element using hash in Angular app

I have read here and here that a page can be scrolled to a specific element using just a hash selector and a id attr.
But for some reasons I am unable to do it in my Angular application. Can this be due to the usage of routing (angular-ui-router) in my app.
What I am trying to do is moving to a specific section of one of my page, which by the way are loaded in to a state using routing.
I have :
<div class="nav_panel">
<a class="nav_links" href="#footer">Footer</a>
</div>
and
<div class="homeFooter" id="footer">
<div class="social_icons">
<span class="gplus"></span>
<span class="fb"></span>
<span class="twitter"></span>
<span class="whatsapp"></span>
<span class="youtube"></span>
</div>
</div>
on the same template.
Is there a way I can make it work with routing (if at all that matters) as well or am I doing something wrong here ?
Based on this answer, you can add the _targetattribute to the <a>tag.
For your need, value on _target is self. It's an attribute compatible with all recent browser, that will redirect you to the link in the same frame as the user click (useful for SPA e.g.)
Go to the footer
<div id="footer">Welcome to the footer</div>

Multiple partial views on AngularJS

I have an AngularJS application that has a list of contents on the menu. When the user clicks on an item on the menu, the content loads on the main view. There are multiple content types:
When "1" is clicked, a video is loaded. When "2" is clicked, a PDF document is loaded, and so on. Content types may repeat and be complex.
Now, I am setting $scope.content when an item is clicked and, depending on its contentType, I'm calling a different directive:
<div class="content" ng-switch on="content.contentType">
<div ng-switch-when="video">
<videoplayer-directive video="content"></videoplayer-directive>
</div>
<div ng-switch-when="pdf">
<pdfreader-directive pdf="content"></pdfreader-directive>
</div>
<div ng-switch-when="...">
<...-directive content="content"></...-directive>
</div>
</div>
Now I have two problems:
When the page is loaded, all the directive templates are automatically loaded. Even if I don't have a PDF in the menu, the pdf template and scripts will be loaded.
Searching for it, I learned that directives should be tiny, not entire modules of my app.
How do I rewrite the switch above so I can comply with the best practices and load the templates and scripts only when needed?
This is exactly what UI-Router is for: Angular UI Router
Decent tutorial on scotch.io
An easier drop-in replacement for your code may be to simply use ng-if. Ng-if won't instantiate the directive until it's called. Just make sure that your directives aren't transcluding the outer div- if that's the case, shut transclusion off, or add another div to wrap them.
<div class="content">
<div ng-if="content.contentType=='video'">
<videoplayer-directive video="content"></videoplayer-directive>
</div>
<div ng-if="content.contentType=='pdf'">
<pdfreader-directive pdf="content"></pdfreader-directive>
</div>
<div ng-if="content.contentType=='...'">
<...-directive content="content"></...-directive>
</div>
</div>

how to use <div ng-view = ""> mulitple times

In my application I have an index.html file where i have loaded all the required scripts and the body contains am empty ng-view whose content will update based on the route url.
The first page is a landing page where I'am showing a button to the user, clicking on which am showing Login Page, by changing the path value of $location.
On Successful login a dashboard page should come where header, sidebar footer area is going to be fixed and only the center area is going to be changed based on the menu clicks which is there in header section, by changing the route value
so the center area i declared as
when am trying to load the dashboard.html page it is going to infinite loop and when am removing the center div which is nothing but an empty view , my view is rendering fine. So the problem is with using the
Can anyone suggest me whether my understanding is corect ??
If yes please suggest me how to achieve my requirement...
index.html
<div class="row">
<div data-ng-view=""></div>
</div>
dashBoard.html
<div class = "row">
<header div here>
<div>
<sidebar div>
**<div data-ng-view = ""></div>** which is not working
</div>
<footer div here>
</div>
I have provided the html code
Thanks
What you're trying to do is not supported by the default router. You can try ui-router which supports multiple and nested views. You can see an example here http://plnkr.co/edit/7FD5Wf?p=preview. The index.html contains the main view.
<body ng-controller="MainCtrl" class="container">
<div ui-view></div>
</body>
Inside contacts.html there is another view
<h1>My Contacts</h1>
<div ui-view></div>
Try checking the difference between route provider and state provider.
Here's a link to ease your search.

AngularJS how to change the view after all the data in the destination controller is loaded?

I have the following structure:
<html ng-app="myApp">
<head>...</head>
<body ng-controller="MainCtrl">
<nav class="side-nav">
...
</nav>
<header>
...
</header>
<main ng-class="navOpen">
<div class="loading-screen" ng-if="!contentLoaded">Loading...</div>
<div class="content" ng-view></div>
</main>
</body>
</html>
MainCtrl handles all "application specific" stuff - navigation (like change the class of a link when route changes), loading screen, hamburger menu being clicked.
Now I want to add transitions between the routes. My idea is that the previous view stays until the contentLoaded variable is set to true. The contentLoaded variable gets set inside each controller; generally after an http request completes. That way I will be able to "blur" the previous content by adding opacity to the loading-screen's background. After content is loaded, the previous view will be switched with the new view and the loading screen will disappear.
Is there a way to tell AngularJS to keep the view until a specific criteria in the controller is met? I am using ngRoute for the routing.

Subviews for elements in AngularJS

I want to have an single-page App (AngularJS) with following views:
Login
Main View
Now the Main-View should have different "elements":
- Toolbar
- Main Content Div
- 2 Sidebars
Can I handle all this elements as a subview? I would like to have a .html Template for each of these "elements".
Thank you very much!
Do not split into two base html. That is not good design for Angularjs apps and it will be creating problem while running test cases (unit or end-2end test cases).
Please look the below code. Here "userLoggedIn" is a $rootscope variable for loading necessary block based on authentication.
<div ng-include="'views/common/loginHeader.html'" ng-show="!userLoggedIn"></div> <!-- loginHeader -->
<div ng-include="'views/common/userHeader.html'" ng-show="userLoggedIn"></div> <!-- userHeader -->
<div class="container" ng-view></div> <!-- body -->>
<div ng-include="'views/common/footer.html'"></div> <!-- footer -->
After authentication, you can set boolean flag or object to that variable.
$rootScope.userLoggedIn= true
(or)
$rootScope.userLoggedIn= {"name":"john smith", "settings":[{}]}
In logout controller, you can set false for hiding authentication containers and redirect to login page.
$rootScope.userLoggedIn= false;

Categories