I'm digging into Angular and have decided to use the Angular Material library to assist in my first application. So far I have some very basic code I copied from https://material.angularjs.org/1.1.0/demo/navBar which I have modified to fit my own needs. I'm having some trouble wrapping my head around routing and the md-nav-items.
<html>
<head>
<title>PRT - CIT</title>
<meta name="viewport" content="width=device-width, initial-scale=1" </meta>
<!-- Angular Material style sheet -->
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"> </head>
<body ng-app="MyApp" id="bootstrap-overrides">
<div ng-controller="AppCtrl" ng-cloak="" class="navBardemoBasicUsage main">
<md-content class="md-padding">
<md-nav-bar md-selected-nav-item="currentNavItem" nav-bar-aria-label="navigation links">
<md-nav-item md-nav-click="goto('queue')" name="queue">Queue</md-nav-item>
<md-nav-item md-nav-click="goto('detail')" name="detail">Detail</md-nav-item>
<md-nav-item md-nav-click="goto('request')" name="request">Request</md-nav-item>
<!-- these require actual routing with ui-router or ng-route, so they won't work in the demo
<md-nav-item md-nav-sref="app.page4" name="page4">Page Four</md-nav-item>
<md-nav-item md-nav-href="#page5" name="page5">Page Five</md-nav-item>
--></md-nav-bar>
<div class="ext-content"> External content for `<span>{{currentNavItem}}</span>` </div>
</md-content>
</div>
<script src="node_modules/angular/angular.js"></script>
<script src="node_modules/angular-resource/angular-resource.js"></script>
<script src="node_modules/angular-animate/angular-animate.js"></script>
<script src="node_modules/angular-route/angular-route.js"></script>
<script src="node_modules/angular-aria/angular-aria.js"></script>
<script src="node_modules/angular-messages/angular-messages.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/svg-assets-cache.js"></script>
<script src="node_modules/angular-material/angular-material.js"></script>
<script src="js/site.js"></script>
<link rel="stylesheet" href="/css/site.css">
</body>
</html>
Here's my JS:
(function () {
'use strict';
var MyApp = angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache', 'ngRoute']).controller('AppCtrl', AppCtrl);
function AppCtrl($scope) {
$scope.currentNavItem = 'queue';
}
MyApp.config(function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/index.html'
, controller: 'AppCtrl'
}).when('/queue', {
templateUrl: '/partials/queue.html'
, controller: 'AppCtrl'
}).when('/detail', {
templateUrl: '/partials/detail.html'
, controller: 'AppCtrl'
}).when('/request', {
templateUrl: '/partials/request.html'
, controller: 'AppCtrl'
});
});
})();
I'm kind of lost as to how I should route the tabs. From what I've read, md-nav-bar has some routing built in, but I've found examples utilizing ngRoute as well ui-router.
I'm also confused as to actually populate my partial views in the
<div class="ext-content"> External content for `<span>{{currentNavItem}}</span>` </div>
I tried using md-nav-href instead of md-nav-click but it just ended up redirecting me to the pages, not populating the content below my tabs/nav-bar; I rolled back the JS I had written and that part of the HTML. I've read the other questions posted in this area that I could find but none addressed rendering different partials based on nav-bar item. Any suggestions? I was thinking I could monitor currentNavItem and have the right partial render based on the value of it, but again, I'm not sure how to actually do the rendering.
Here is a Plnker that doesn't render correctly in the preview for some reason, but the code is the same as what I have locally.
Here is an image of what it looks like running locally.
Thanks in advance!
Final Edit:
S/O to #Searching for helping me get it working below. I've updated the plnker link to reflect the changes. Note it gets a little laggy due to the base append script.
ngRoute: When $route service you will need ng-view container. This will be used to load all you routed pages.
You do not have a goto() so just use simple md-nav-href tags to navigate around. The currentNavItem is set by md-selected-nav-item which is not what you need. Let's route with your setup
index.html : update your links to look like this. Use md-nav-href
<md-nav-item md-nav-href="queue" name="queue">Queue</md-nav-item>
index.html : when using html5Mode you will need base tag. Instead of manually specifying it just use the script below. Make sure you load angular.js before this script.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
<script type="text/javascript">
angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));
</script>
script : enable html5molde, why.. too many resources out there. I encourage you to lookup :)
MyApp.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true)
$routeProvider.when('/', {
templateUrl : 'index.html',
controller : 'AppCtrl'
}).when('/queue', {
templateUrl : 'queue_partial.html',//actual location will vary according to your local folder structure
controller : 'AppCtrl'
}).when('/detail', {
templateUrl : 'detail_partial.html',
controller : 'AppCtrl'
}).when('/request', {
templateUrl : 'request_partial.html',
controller : 'AppCtrl'
});
});
Related
Trying to replicate a simple routing example w3schools, but it keeps crashing with "RangeError: Maximum call stack size exceeded" in the console, when accessing index.html.
I tried to add/remove parts of the code to isolate the problem, and the crash seems to happen at <div ng-view></div>. Why is that? The changes I made from the original example are not that drastic.
Here is the code
index.html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="myApp">
Red
Green
<div ng-view></div>
</body>
</html>
app.js
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/", {
templateUrl : "index.html"
})
.when("/red", {
templateUrl : "red.html"
})
.when("/green", {
templateUrl : "green.html"
});
});
red.html
This is red
green.html
This is green
Yes, index is a container for other views. You should put a partial view instead of index. The problem is here:
$routeProvider
.when("/", {
templateUrl : "index.html"
})
That template url will load the complete index.html inside ng-view, which will load another index.html with a new ng-view to the infinite and Secula Seculorum.
The easy fix: create a new view (like the other routes you have) and put it in the templateUrl
You are looping the app with this statement.
$routeProvider
.when("/", {
templateUrl : "index.html"
})
You should another separate template that stands as your main template not index.html
I have my app.js and controller.js files stored in a js folder for the project, here's a snippet of each
app.js
var myApp = angular.module('myApp', ['ngRoute','RouteControllers']);
myApp.config(["$routeProvider",function ($routeProvider) {
$routeProvider
.when("/", {
templateUrl: 'templates/home.html',
controller: 'HomeController'
}).
when("/about", {
templateUrl: 'templates/biography.html',
controller: 'BiographyController'
});
}]);
controller.js
angular.module('RouteControllers', [])
.controller('HomeController', function($scope) {
$scope.title = "Welcome to Website!"
console.log("HomeController: I was instantiated!")
})
.controller('BiographyController', function($scope) {
$scope.title = "About"
});
Then I have my index.html file, the basics:
<base href="/">
<link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/style.css">
<body ng-app="myApp">
Home
About
<div ng-view> </div>
<script src ="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controller.js"></script>
</html>
My issue is that the text from the home page is shown when I load the page (as it should) but then when I click on about I get the following come up instead:
'Page Not Found
This specified file was not found on this website. Please check the URL for mistakes and try again.
Why am I seeing this?
This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.'
The error in the console is simply 'Failed to load resource: the server responded with a status of 404 ()'
I have been searching for what the issue is but can't find one, the url when I click on about is 'http://localhost:5000/about'.
You will need to add the # to your anchors
Home
About
this will make it works. Also, you have the option to do it programmatically using the $location service
.controller('HomeController', ['$scope', '$location', function($scope, $location) {
$scope.title = "Welcome to Website!";
console.log("HomeController: I was instantiated!");
$scope.goAbout = function() {
$location.path('/about');
};
}])
Now you can use the goAbout funtion in your template
<div>
<h1>{{title}}</h1>
<button ng-click="goAbout()">About us</button>
</div>
But, if you want to take advantage of the HTML5 mode, get rid of the # and have prettier url , at least in the browsers that support the HTML5 mode, then you need some updates in your code
myApp.config(["$routeProvider", '$locationProvider',
function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
......
Inject the $locationProvider service and set $locationProvider.html5Mode(true);
If you don't need the <base href="/"> tag, then use an object like this
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
Now, your links need to change
Home
About
And you will have prettier urls. Please, notice that HTML5 mode may need some server side configuration in order to redirect all the navigation to your index page
Hope it helps
I'm new to angular and am having a hard time getting ngRoute to pick up my template file.
Here is my index.html:
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="app.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/main.css" />
</head>
<nav>
<div>
<ul>
<li>home</li>
</ul>
</div>
</nav>
<body>
<div ng-view>
</div>
</body>
</html>
Here is my app.js:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.controller('MainCtrl', function($scope) {
$scope.message = 'Hello World';
});
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'pages/home.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/home'
});
}]);
Here is my pages/home.html:
<div ng-controller="MainCtrl">
<p>Test</p>
<p>{{ message }}</p>
</div>
I can see that it is appending #/ to the root url so perhaps this is partially working; however, it doesn't seem to be rendering the template at "pages/home.html".
I've checked the cdn url's to make sure there wasn't any version inconsistencies, and what not, but that doesn't seem the be the case.
This is pretty much my first Angular project, and I've just been going off of the docs, but there must be something I'm not seeing. Coming from other server side projects, the lack of stack trace is killing me haha.
Is there something I'm missing in the above code, that is preventing my template from being rendered in '/'?
Thanks!
This is my code and it is working fine, you cam take help from it.
var EventList = angular.module("EventList", ['ngRoute' ,'infinite-scroll']);
EventList.config(function($routeProvider) {
//$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: 'views/business/business_home_events.html',
controller: 'EventListController'
});
});
EventList.controller('EventListController', ['$scope', '$http', '$route', function($scope, $http, $route){
// Do your work
}]);
the problem is with your when ('/'). Since your url has #/home - it looks in the .when to find that route.
change it to
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/home', { // <-
templateUrl: 'pages/home.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
}]);
This was an annoying one, but I think I figured it out.
I was encountering this issue while testing locally (no nodejs) on Chrome; however, sure enough when I popped it open in Safari it was working. It seems that ngRoute chokes on local files in Chrome.
I found a reference to the issue here, which is closed, so I'm guessing if I update to a newer version I shouldn't have this issue.
https://github.com/angular/angular.js/issues/4680
Setting up a web server should resolve this problem.
Why AngularJS routes are not working in local?
I have executed you code and is working fine on mozilla.
However, there is an issue in chrome of cross origin request if we run the file without putting in server.
But it is working fine on chrome also if you will put it on server (may be xampp/wampp) and run the file. The angular library you are using have http request to another server.
I have spent hours and hours searching and googling to find out why my ngRoute is not working but couldn't find the solution so i decided to come here. Here is my code::
"app.js"
angular.module("sandwichApp",["cart", "ngRoute"])
.config(['$routeProvider', function($routeProvider){
$routeProvider
.
when("/",{
templateUrl: "app/views/sandwichList.html",
controller: "SandwichListController"
}).
when("/sandwichList",{
templateUrl: "app/views/sandwichList.html"
}).
when("/checkout",{
templateUrl: "app/views/cart.html"
}).
otherwise({
redirectTo: "/app/views/sandwichList.html"
});
}]);
// for this particular code i have tried the version where the config() doesn't contain array "[]" but only the function and it also doesn't work
"sandwichListController.js"
var main = angular.module("sandwichApp", ["clientAppServiceModule"]);
main.controller("SandwichListController", function($scope, ClientAppService, cart){
$scope.original = {
sandwiches : []
}
//.... more code here. THERE IS NO PROBLEM WITH THIS CONTROLLER SO THE CODE IS NOT IMPORTANT.
);
"index.html"
<!DOCTYPE html>
<html ng-app="sandwichApp">
<head>
<meta charset="UTF-8">
<title>title</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-route.js"></script>
<!--script src="https://cdn.jsdelivr.net/angularjs/1.5.5/angular-route.min.js"></script-->
<script src="app.js"></script>
<script src="app/services/clientAppService.js"></script>
<script src="app/controllers/sandwichListController.js"></script>
<script src="app/model/cart.js"></script>
</head>
<body ng-controller="SandwichListController">
<div><strong>Heading & Cart</strong></div>
<div ng-view></div>
</body>
</html>
"sandwichList.html"
<div>
<b>Your Cart: </b>
{{totalItems}} items / {{totPrice | currency}}
<span>checkout</span>
</div>
<div>
<input type="text" ng-model="sandwichName" ng-change="filterSandwich()"/>
</div>
<div>
<h1>Sandwiches </h1>
</div>
<div ng-repeat="sandwich in workingCopy.sandwiches">
<h3 ng-click="addItemToCart(sandwich)">
<strong>{{sandwich.Name}}</strong>
<span>{{sandwich.Price | currency}}</span>
</h3>
</div>
When i load the "index.html" page, i expect the "otherwise" section of the routeer to display the "sandwichList.html" in the <div ng-view></div> section but it doesn't work. If it can't find the file, it will complain but it doesn't complain meaning that the file is at the right location. Yet it does not work.
In the sandwichList page at least if the controllers will not work, it must be able to display the <h1>Sandwiches </h1> .
My chrome console doesn't display any errors so i don't know what is causing the problem
I think it might be because you are accidentally declaring your app twice. When registering a new module in angular you provide it a second parameter which is an array of dependencies. You are doing that where you specify your routes. However, when you go to create your controller, you're code is this:
var main = angular.module("sandwichApp", ["clientAppServiceModule"]);
Angular sees the dependencies and assumes it is to create a new app. When it realizes there is already one with the same name, it overwrites it and you lose all the route stuff you setup. Try passing your "clientAppServiceModule" to the initial app definition, then just creating your controller by doing this:
angular.module("sandwichApp").controller("SandwichListController", function($scope, ClientAppService, cart){
$scope.original = {
sandwiches : []
}
//.... more code here. THERE IS NO PROBLEM WITH THIS CONTROLLER SO THE CODE IS NOT IMPORTANT.
);
Let me know if you have any questions, or if that doesn't solve it.
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.