Angularjs Client-Side Routing with ui-router - javascript

I use ui-router (states) for my routing:
$urlRouterProvider.otherwise('/Home');
$stateProvider
.state('home', {
url: '/Home',
templateUrl: '/Home/Home',
controller: 'MainCtrl'
})
.state('posts', {
url: '/Posts',
templateUrl: '/Home/Posts',
controller: 'PostCtrl'
});
$locationProvider.html5Mode(true);
In html I have something like this:
<html>
<head>
<base href="/" />
<!--render scripts -->
<title>My Angular App!</title>
</head>
<body ng-app="flapperNews" ngcloak>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ul>
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="posts">Posts</a></li>
</ul>
<ui-view></ui-view>
</div>
</div>
</body>
</html>
When I use my menu links (Home, Posts) the app works fine and updates my view in <ui-view></ui-view> as needed. When I use the address bar after the first download to change the url to localhost:port/Posts, the app refreshes the page.
Keep in mind that I removed # from links.
Why does angular not know about my routes?
Or how can I set client-side menu with angular?

Angular Knows about your route but you webserver may thinks he need to show the index.html page in the map posts
Try to set your html5Mode to false and see if it still happens
the this link and look at the part about Hashbang and HTML5 modes
and especially the last row requires server-side configuration: Yes

Related

Login Page without Index.html Design - ngRoute (AngularJS)

I'm using ngRoute to do the routing of my AngularJS application (myApp) but I have a problem: I don't know how to NOT APPLY my index.html design (with all my sidebars) to my login.html page, which seems to be applied by default if it is defined as a view. I want a simple design for my login.html page: only two fields to fill out, without the design of my index.html, which is applied to all the views in myApp. Thereby, I don't know how to do my routing to accomplish such task. Thank you very much.
<-- This is a sample of how I do my routing in myApp (for only one view - "/view1") -->
Sample of app.js:
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'ngResource',
'ui.bootstrap',
'ngCookies',
'myApp.view1',
])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
For each view there is a .js file associated where I defined its routing and controllers. For instance, for view "/view1" - view1.js:
'use strict';
angular.module('myApp.view1', ['ngRoute', 'ngResource'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', function($scope) {
// something
}]);
And a sample of my index.html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<script src="view1.js"></script>
<-- MORE SCRIPTS ARE LOADED -->
</head>
<body class="hamburg" ng-controller="MasterCtrl">
<-- SIDEBARS ARE DEFINED -->
<div id="content-wrapper">
<div class="page-content">
<!-- Main Content -->
<div class="row">
<div class="col-xs-12">
<div class="widget">
<div class="widget-body">
<div ng-view></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
Given the situation above looks like you want two page layout (page design or page template), the first one is now used in index.html, and the second one you want to use in login.html which just has two fields to fill out. So angular-ui/ui-router (doc url: https://github.com/angular-ui/ui-router/wiki) could be the solution to this issue.
The idea behind that is ui-router has a very powerful tool named ui-view which you can see it as a layout or template. So when the path is on any page other than login page like /index or /home use one ui-view, and on /login page then use another different ui-view.
For a rough example:
index.html page:
<html>
<head></head>
<body>
<div ui-view="layout"></div>
</body>
</html>
I assume you will reuse the head part, so just wrap every thing from the body in the original index.html and put into the new index.html. Same to the login page login.html.
config file:
$stateProvider
.state('index', {
url: '/index',
views: {
layout: {
templateUrl: "/path/to/index.html"
}
},
controller: 'indexController'
}
.state('login', {
url: '/login',
views: {
layout: {
templateUrl: "/path/to/login.html"
}
},
controller: 'loginController'
})
So what does the code above do is very similar to what you did with $routeProvider, it defines on which url use which controller and to load which view.
Hope this can help you, if any question let me know please.
You need to create your login page as a diferente ngApp, store your sesion on the localSotarge in case of a successfull login and then redirect to you main ngApp.
In your main ngApp, validate if a session exists in the localStorage and redirecto to the loginApp if it dont.
I know it sounds a bit like overdoing stuff, but I have not found any other solution in my 3 years working with AngularJS. Now, keep in mind that this is necesary because you need to NOT TO APPLY your index.html, and the only way to do that is using another ngApp.
Routing is used for injecting views in angular SPA. What I get from from your question is you need a login dialog.
For that you may look ngDialog or uibDialog
In your case you need to load new layout. I understand, for login and for application there is mostly different layout. This operation is equal to redirecting page to new location. With new angular app and controllers for login. You can use:
$window.location.href="new/layout/template".
Read more # Angular Dev Docs.

How does one map many routes in AngularJS?

An AngularJS site with a Spring Boot backend has numerous public url patterns in addition to a secure section. All the public url patterns fall in the model mydomain.com/public1, mydomain.com/public2, mydomain.com/public3, and so on, while all the secure content will be inside the mydomain.com/secure url pattern like mydomain.com/secure/one_of_many_urls. The problem is that the sample app I am starting with has separate modules for every route. This would become hard to maintain with n routes.
How can I set the code up so that all the public1, public2, public3, public_n routes share a single controller?
Here is the current directory structure. I would like for the public1 directory to turn into public and be able to map as many specific url patterns as I want to put into it:
In addition, my public1.js is currently empty as follows:
angular.module('public1', []).controller('public1', function($scope, $http) {
});
The link to the public1 route is handled in a navigation bar in index.html as follows:
<!doctype html>
<html>
<head>
<title>Hello Angular</title>
<!-- To produce natural routes (without the #), you need an extra <base/> element in the header of the HTML in index.html, and you need to change the links in the menu bar to remove the fragments ("#"). There are also changes in a spring controller and in the main js module. -->
<base href="/" />
<link href="css/angular-bootstrap.css" rel="stylesheet">
<style type="text/css">
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none !important;
}
</style>
</head>
<body ng-app="hello" ng-cloak class="ng-cloak">
<div ng-controller="navigation" class="container">
<ul class="nav nav-pills" role="tablist">
<li ng-class="{active:tab('home')}">home</li>
<li ng-class="{active:tab('message')}">message</li>
<li ng-class="{active:tab('public1')}">public1</li>
<li>login</li>
<li ng-show="authenticated()">logout</li>
</ul>
</div>
<div ng-view class="container"></div>
<script src="js/angular-bootstrap.js" type="text/javascript"></script>
<script src="js/auth/auth.js" type="text/javascript"></script>
<script src="js/home/home.js" type="text/javascript"></script>
<script src="js/message/message.js" type="text/javascript"></script>
<script src="js/public1/public1.js" type="text/javascript"></script>
<script src="js/navigation/navigation.js" type="text/javascript"></script>
<script src="js/hello.js" type="text/javascript"></script>
</body>
</html>
And public1.html is:
<h1>Public 1</h1>
<div>
<p>This will be a public url pattern.</p>
</div>
How do I change the code below so that a scaling n number of public routes can efficiently share the same controller? Each public_n route will have their own images, but would share js logic, if they have any js logic.
I found the following, but where would one put it in the code above, and how would a person link everything to it without resorting to leaving it in hello.js?
.when('/public1', {
templateUrl: 'js/public/public1.html'
}
.when('/public2', {
templateUrl: 'js/public/public2.html'
}
.when('/public3', {
templateUrl: 'js/public/public3.html'
})
How do I change the code below so that a scaling n number of public
routes can efficiently share the same controller?
You can Associate one Controller to Many Routes (Views) just assigning it to more routes in your $routeProvider as follows:
myApp.config(function ($routeProvider) {
$routeProvider
.when('/public1', {
templateUrl: 'js/public/public1.html',
controller: 'myController'
})
.when('/public2', {
templateUrl: 'js/public/public2.html',
controller: 'myController'
})
.when('/public3', {
templateUrl: 'js/public/public3.html',
controller: 'myController'
})
.otherwise({
redirectTo: '/'
});
})
You can also Set a Controller Alias as follows:
.when('/public1', {
templateUrl: 'js/public/public1.html',
controller: 'myController',
controllerAs: 'myCtrl'
})
I found the following, but where would one put it in the code above,
and how would a person link everything to it without resorting to
leaving it in hello.js?
If I got your question, you just need to put the $routeProvider in a separated routeProvider.js file and include it in your index.html. Same thing for your controller/controllers.
I suggest you to take a look at:
AngularJS Controllers Documentation
AngularJS $routeProvider Documentation
Follow the first lesson of - CodeSchool - Staying Sharp with AngularJS
EggHead.io AngularJS Screencasts
And also take a look at those Q/A on StackOverflow:
Using one controller for many coherent views across multiple HTTP requests
Views sharing same controller, model data resets when changing view
Controlling multiple views in one controller in AngularJS
Can I use one controller updating two views in AngularJS?
I hope I've been helpful.

AngularJS routing doesnt work

I'm new to AngularJS and I'm currently building a small application. I want my URL's like this /index (without the .html). I tried to use NgRoute for that, but it doesn't seem to work out well. When i go to /establishments, it says the route doesn't exists. Here is my code:
app.js
var app = angular.module('khApp', ['ngRoute','establishmentModule', 'queryModule', 'buildingBlockModule', 'categoryModule']);
app.config(['$routeProvider', function($routeProvider)
{
$routeProvider
.when('establishments', {controller:'testController', templateUrl: '../html/establishments.html'})
}]);
app.controller('testController', ['$http', function($http)
{
}]);
index.html
<div ng-controller="testController as test" class="container">
hi
<a href="establishments">
<button class="btn btn-default">Start</button>
</a>
</div>
<ng-view></ng-view>
<script type="text/javascript" src="../../bower_components/angular/angular.js"></script>
<script type="text/javascript" src="../../bower_components/angular-route/angular-route.js"></script>
<script type="text/javascript" src="../js/app.js"></script>
<script type="text/javascript" src="../js/buildingblock.js"></script>
<script type="text/javascript" src="../js/category.js"></script>
<script type="text/javascript" src="../js/establishment.js"></script>
<script type="text/javascript" src="../js/query.js"></script>
</body>
</html>
What am i doing wrong? Thanks in advance!
Depending on how your router is configured, typically you need to target routes beginning with a slash like so:
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('establishments', {
controller:'testController',
templateUrl: '../html/establishments.html'
});
}]);
In addition, in your HTML, I think your HTML anchor tags need to begin with the hash navigation like so:
<a href="#/establishments">
<button class="btn btn-default">Start</button>
</a>
Reference: AngularJS Documentation Tutorial 7 - Routing & Multiple Views
AngularJS routing utilizes the fragment identifier (the # in the URL) to get its routes. That's because it can't manipulate the full URL without causing the browser to request a new page, thus making it not a SPA.
So the URL you need to request should be the form of <path to root>#/establishments. Assuming index.html is in /application/app/html, the URL to request would be:
/application/app/html/index.html#/establishments
If you also want to support the URL localhost:port/application/app/html/establishments then you need to configure your server side routing to perform a redirect to /application/app/html/index.html#/establishments.
#/establishments is what you need in your anchor tag
<a href="#/establishments">
<button class="btn btn-default">Start</button>
</a>
your route will be something like this:
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('establishments', {
controller:'testController',
templateUrl: '../html/establishments.html'
});
}]);

ngRoute- direct url not displaying template

I'm newer to angular so I'm sorry if this is really obvious! I'm making a super basic app and right now all I want is when a user directly goes to a page it should always display the layout and the content. I am using angular's ng-route.
As of right now, if I go to localhost:8080/ it displays the layout(index.html) and content(view/home.html). If I click on the 'About' link, it goes to localhost:8080/about and displays the layout(index.html) and the correct content(view/about.html). Now if I type localhost:8080/about in my address bar, hit enter, I get a 404 error from my server's log. I'm not sure what I'm missing. Any input appreciated!
app.js
angular
.module('TestProject', ['ngRoute']);
routes.js
angular.module('TestProject')
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl : 'views/home.html'
})
.when('/about', {
templateUrl: 'views/about.html'
})
.when('/contact', {
templateUrl: 'views/contact.html'
})
.otherwise({
redirectTo: "/"
});
$locationProvider.html5Mode(true);
});
index.html
<!DOCTYPE html>
<html lang="en" ng-app="TestProject">
<head>
<meta charset="utf-8">
<title>Test!</title>
<base href="/">
<link rel="stylesheet" href="assets/styles/app.css">
</head>
<body>
<header><h1>Logo</h1></header>
<nav>
<ul class="main">
<li>
<div class="navBorder">
About
</div>
</li>
<li>
<div class="navBorder">
Contact
</div>
</li>
</ul>
</nav>
<div ng-view></div>
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="routes.js"></script>
</body>
</html>
I know I don't have any controllers yet, I just started this project and there's nothing there yet.
Here are how my files are organized:
My file structure is below:
/index.html
/app.js
/routes.js
/views/home.html
/views/about.html
/views/contact.html
If using AngularJS 1.3+, you need to include a notion of a <base href="" />. You can do this in your <head> tag as such
<head>
<base href="/">
...
From the docs
Before Angular 1.3 we didn't have this hard requirement and it was
easy to write apps that worked when deployed in the root context but
were broken when moved to a sub-context because in the sub-context all
absolute urls would resolve to the root context of the app. To prevent
this, use relative URLs throughout your app:
Additionally, without this <base /> tag, you can declare .html5Mode() as such... You'll need to take one of these two approaches.
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
Ahhh I figured it out, it was a problem with my server. I had not set up mod_rewrite for it to work properly. For the time being I turned off html5Mode() and everything works fine.

AngularJS routing to static file

I have a simple angularjs app, with ngRoute module for routing in html5Mode.
How can I have a link to some static file on my page, and not to have it intercepted by angular routing module?
Here's the example:
HTML:
<head>
<base href='/'></base>
</head>
<body ng-app="crudApp">
Home
User
users.html
<div ng-view></div>
JS routing:
$routeProvider
.when('/', {
templateUrl: 'app/components/home/homeView.html',
controller: 'HomeController'
})
.when('/user', {
templateUrl: 'app/components/user/userView.html',
controller: 'UserController'
})
.otherwise({
redirectTo: '/'
});
When I click on User link I get routed to localhost:8080/user, and my controller and template work fine. When I click on users.html link I get routed to home, but I want to invoke a static home.html page.
From the AngularJS docs, you have 3 options:
Html link rewriting
(...)
In cases like the following, links are not rewritten; instead, the browser will perform a full page reload to the original link.
Links that contain target element
Example: link
Absolute links that go to a different domain
Example: link
Links starting with '/' that lead to a different base path
Example: link
What you might be looking for is the first example:
users.html

Categories

Resources