Multiple views with angular - javascript

So I am trying to display multiple views in angular to help fix the footer problem I am having with this site I am building. I want to make sure that what I have been reading about and trying to mimic is making sense. This is what I have so far.
index.html
<!--Do not code below this line-->
<main ng-view="header"></main>
<main ng-view="body"></main>
<main ng-view="footer"></main>
routes.js file
angular.module('appRoutes', ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
views: {
'header': {
temmplateUrl: 'app/views/header.html'
},
'body': {
templateUrl: 'app/views/body.html'
},
'footer': {
templateUrl: 'app/views/footer.html'
}
}
})
I have it working where I have just one view and have my header and footer inside the index.html file but I saw that you can have multiple views and really just switch out the "body" view with other pages.
Any advice would be much appreciated. Thank you

To display multiple views you could use only ng-include.
See https://docs.angularjs.org/api/ng/directive/ngInclude for more ngInclude details.
Here is a example: (notice the wrap in single quotes)
<div id="header">
<div ng-include="'header.html'"></div>
</div>
<div id="content" ng-view></div>
<div id="footer">
<div ng-include="'footer.html'"></div>
</div>
Use ngRoute with ng-view to define a region (e.g div#content) where will be changed the dynamic content (as partial html).
See https://docs.angularjs.org/api/ngRoute/directive/ngView for more ngRoute details.
Good luck!

You can have just one ng-view.
You can change its content in several ways: ng-include, ng-switch or mapping different controllers and templates through the routeProvider.
Alternatively, use ui-router

Related

Should I use ng-app directive in every page for a non single page application?

I am developing a web application for a game using MVC but the views are different (there is a CreateGameView.html, a GameView.html ...) meaning there is not a shared navigation bar. I am using AngularJS.
When clicking some buttons in a page some Controller perform some action and then another View (html page) is loaded.
The question is should I use the ng-app directive in each html page using a Controller?
I would just use one ng-app directive. Instead use ngroute to control your view. There is a short tutorial on w3schools: https://www.w3schools.com/angular/angular_routing.asp
Below is the gist of it.
index.html
<body ng-app="myApp">
<!-- if you wanted a common navbar -->
<navbar></navbar>
<div ng-view></div>
</body>
starScreenView.html
<p>New Game</p>
<p>Load Game</p>
createGameView.html
<p>This will be the create game view</p>
<p>Main Menu</p>
<p>Load Game</p>
gameView.html
<p>This will be the game view</p>
app.js
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/", {
templateUrl : "startScreenView.html",
controller: "startScreenCtrl"
})
.when("/createGame", {
templateUrl : "createGameView.html",
controller: "createGameCtrl"
})
.when("/loadGame", {
templateUrl : "gameView.html",
controller: "gameViewCtrl"
})
});
What is happening is the ng-view is being replaced with the templateUrl html page, and this block has the controller wrapped around it.
For each routing end point you can have a page, controller, pass parameters around, etc. Just search google for ngroute examples.
If you must have separate HTML pages and you plan to use Angular on all of those pages then you need an ng-app on all those pages.
Otherwise use the router or craft your own way of swapping page content. If you page is simple enough you may not need the extra size of the router.

Why is my header logo appearing twice in my angular app?

With angular, I have my index.html setup as follows.
<html><head>...</head>
<body ng-app="someappname">
<header>
<img src="images/hdr_logo.png" alt="...">
</header>
<main>
<!-- this is where the active view will be placed -->
<ui-view></ui-view>
</main>
</body></html>
And I have my ui-router setup as follows.
$stateProvider
.state('index', {
templateUrl: 'index.html',
controller: 'IndexController',
abstract: true
})
.state('index.login', {
url: '/login',
templateUrl: 'partials/login.html',
controller: 'LoginController',
})
Currently, my login.html has nothing but text... simply looks like this.
This is my login page
However, when I run the application I see that my header logo is being displayed twice. Upon further investigation, I can see that my <ui-view></ui-view> actually re-includes the entire index.html again (as well as the text). So there is index.html which has another copy of index.html within the ui-view. My display has the logo displayed twice followed by the text, "This is my login page".
Why is the index.html being included within my ui-view, instead of just the partial?
After much toil and trouble, it seems that problem was to do with the keyword abstract not being functional in the versions that I was using. Since, whether I added or removed abstract the result was the same. However, after I upgraded my angular and ui-router version... everything works!!!

In Angularjs with ui-router how to change hash without reloading controller but keeping subviews routing enabled

In short: my demo, how to have subviews? (without reloading page)
Longer:
I'm using snapscroll to provide different screens effect (demo). This directive doesn't support by default ui-router so I had to do it myself.
When you move the mouse wheel beforeSnap event event is triggered. I call ui-router $state.go to change URL hash. I don't reload the controller.
$scope.beforeSnap = function (snapIndex) {
$state.go('view' + snapIndex,{},{
notify:false,
reload:false,
location:'replace',
inherit:true
});
};
Routing is like
.state('main', {
url: '/',
templateUrl: 'views/screens.html',
controller: 'mainCtrl'
})
.state('view0', {
url: '/green',
templateUrl: 'views/screens.html',
controller: 'mainCtrl',
params: {'color': 'green', 'screenIndex': 0}
})
[...]
views/screens.html:
<div fit-window-height="" snapscroll="" snap-index="snapIndex" before-snap="beforeSnap(snapIndex)">
<div class="green"></div>
<div class="blue">
<!-- How to enable these subviews? -->
<!-- <a ui-sref="view0.a">Go to view0.a</a> -->
<!-- <a ui-sref="view0.b">Go to view0.b</a> -->
<div ui-view="view1"></div>
</div>
<div class="red"></div>
<div class="yellow">
<div ui-view="view3"></div>
</div>
</div>
You can see a codepen and a demo.
The issue is that I want to have subviews in some "screens" (colours divs), e.g: view1 and view3.
But I don't know how to do it without reloading the whole page. Subviews like:
/view1/a
/view1/b
/view3/a
/view3/b
/view3/c
Besides, I think screens would be better/cleaner being children of main main.view0, main.view1, etc.
I read about multiple named views in ui-router and nested states without success.

Angular.js routing: how do I reach endpoint routes?

After trying all I can imagine, and reading several posts here, I think I need your help!
I have a webapp based on node and express on the server and Angular on the client. I am using angular routing.
BASIC INFO
I have the routing set up like the following:
mainApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'initial.ejs',
controller: 'controllerInitialView'
})
.when('/home/post', {
templateUrl: 'post.ejs',
controller: 'controllerAddPost'
})
.... other /home/something routes ..
.otherwise({
redirectTo: '/home'
});
}
]);
The html template is organized as follows:
<div class="container-fluid">
<div class="row">
<!-- Left Columns: With links to views -->
<div class="col-xs-2 home-bd-dx">
<ul>
<li>
Post
</li>
...
<li>
Logout
</li>
</ul>
</div>
<!-- Central Columns: Here the views are inserted -->
<div class="col-xs-10">
<div ng-view></div>
</div>
</div>
</div>
The issue is with the Logout link. I have a server serverapp.get('/logout') link which uses passport.js to logout the user. However, I cannot manage to reach that link. Whatever I try transforms my /logout, into /home/logout, and it is handled by Angular rather than by the server.
QUESTION
So here is the question: how can I create links to endpoint routes in Angular without Angular router intercepting them?
ADDITIONAL INFO IF NEEDED
The express server is has a route serverapp.get('/home/*') which delegates these routes to Angular.js by returning the template I sketched above.
I tried with and without a <base href="/home"> tag in the <head> with no luck
I tried creating a route '/home/logout', and then having the angular $window.location.href="/logout"; in the controller of /home/logout. No luck also in this case.
If I understand you correctly, what you're trying to do is disabling deep linking for certain URLs. You can do that by adding target="_self" to the <a> tag.
Try this:
Logout
Now the URL the link is pointing to will be handled by the server instead of Angular.

AngularJS ui router - not showing nested partials views

I have an AngularJs app with start up page as index.html, by default the projects view will be displayed and on top of the page I am showing a icon to show the todo items (for the logged-in user) which I am using bootstrap's data-toggle dropdown. The issue is whenever I click the todo link the partial view (todo.html) is not showing. BTW, I am new to the angular world so please forgive me if there is anything silly. Please see the code below:
Index.html
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head></head>
<body>
<a data-toggle="dropdown" class="dropdown-toggle" ui-sref=".todo">
<i class="icon-tasks"></i>
<span class="badge badge-grey">4</span>
</a>
<div ng-view></div>
</body>
app.js
// For any unmatched url, redirect to /projects
$urlRouterProvider.otherwise("/projects");
//
// Now set up the states
$stateProvider
.state('projects', {
url: "/projects",
templateUrl: "/app/views/projects/projects.html",
controller: "projectController"
})
.state('projects.todo', {
url: "/todo",
templateUrl: "/app/views/todo/todo.html"
});
First of all replace ng-view with ui-view in the root template, cause it seems you want to use ui-router instead of ng-router.
Wrap the content of your template files with div of ui-view as a parent element.
/app/views/projects/projects.html
/app/views/todo/todo.html
<div ui-view>
... previously defined content ...
</div>
Let's say your view was
<div class="container">
<div class="page-header">
<h1>Title: {{title}}</h1>
</div>
</div
you need to add ui-view to the div
<div class="container" ui-view>
<div class="page-header">
<h1>Title: {{title}}</h1>
</div>
</div
or wrap your view with div containing ui-view descriptor in case your vie contains several tags.
I cannot show you an example since you did not provide content of view files.
/app/views/projects/projects.html
/app/views/todo/todo.html
The issue is that after fist template applying angular does not see the place to put new template anymore.
ui-router isn't really supposed to be used in this way. To integrate bootstrap with angular you want to look at UI Bootstrap - http://angular-ui.github.io/bootstrap/
Then to achieve your drop down, look at their basic examples. If you want to use separate view files to define your drop down content, you can use <div ng-include="'mycontent.html'"></div>.
ui-router is useful if you have a complex view hierarchy, where you are for example, looking for dynamic loading of children, while keeping parent states static.
In ui-router you defined all of this in the $stateProvider, so there you should define that you have a view that has another view belonging to it, example:
<!-- In index.html the main view that will have all the page views-->
<div id="main" ui-view="main"></div>
<!-- In todo.html with a partial with the dropdown code in dropdown.html -->
<h1> This is a nice todo drop down </h1>
<div id="todoDropDown" ui-view="todoDropDown"></div>
//In your app file
.state('projects.todo', {
url: '/todo',
views: {
'main#': {
templateUrl: '/app/views/todo/todo.html',
controller: 'TodoCtrl'
},
'todoDropDown#projects.todo': {
templateUrl: '/app/views/partials/dropdown.html'
}
}
})
"todoDropDown#projects.todo" This does the magic, it tells that this view has another view inside. And you can add controller to it and all other options you have in ui-router. In this way you can break up as much as possible reusable parts.

Categories