I'm new to angular and trying to learn it, so I guess this is a pretty basic question,
I am trying to use ng-view, so far with no success.
this is my code:
HTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello world</title>
<script src="~/scripts/refernces/jquery-1.10.2.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="~/scripts/refernces/angular.min.js"></script>
<script src="~/scripts/refernces/angular-route.min.js"></script>
<script src="../../scripts/App/myApp.js"></script>
</head>
<body ng-app="myApp">
<nav class='navbar navbar-default'>
<div class='container-fluid'>
<div class='navbar-header'>
<a class='navbar-header' href='Home'>Demo Site</a>
</div>
<div>
<ul class='nav navbar-nav'>
<li class='active'><a href='#Home'>Home</a></li>
<li><a href='/#About'>About</a></li>
<li><a href='/#Contact'>Contact</a></li>
<li><a href='/#Other'>Other</a></li></ul></div</div></nav>"
<div ng-view></div>
</body>
JS:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when("#About", {
template: '<h1>about</h1>'
})
.when("Contact",
{
template: '<h1>Contact</h1>'
});
});
I've tried declaring 'when' with and without the '#' sign, and I know Angular is loading fine (I have a controller that acts as I expect and I don't have any errors in the console) but I can't seem to make the routing work.
Tnx
If you set $locationProvider.html5Mode to true, you need to add:
<base href="/">
in the head of the document.
Also you do not need to use the hash in the href.
So give this code a try:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<base href="/">
<title>Hello world</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.angularjs.org/1.4.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.4.9/angular-route.min.js"></script>
</head>
<body ng-app="myApp">
<nav class='navbar navbar-default'>
<div class='container-fluid'>
<div class='navbar-header'>
<a class='navbar-header' href='Home'>Demo Site</a>
</div>
<div>
<ul class='nav navbar-nav'>
<li class='active'><a href='Home'>Home</a></li>
<li><a href='/About'>About</a></li>
<li><a href='/Contact'>Contact</a></li>
<li><a href='/Other'>Other</a></li>
</ul>
</div
</div>
</nav>
<div ng-view></div>
<script>
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when("/About", {
template: '<h1>about</h1>'
})
.when("/Contact",
{
template: '<h1>Contact</h1>'
});
});
</script>
</body>
You are actually pretty close, first off, one small typo in your html:
<<li><a href='/#Other'>Other</a></li></ul></div</div></nav>
^^^ missing end caret
Next up, we can talk about ngRoute's HTML5 mode. You explicitly set HTML5 mode to true, which means that angular is going to attempt to use all links you provide it as actual URLs, instead of append a URL fragment (#fake/url/here) to the current url and using that for routing. THe difference looks like this:
HTML5 mode == true
http://yoursite.com/angularPage/Contact
http://yoursite.com/angularPage/About
HTML5 mode == false
http://yoursite.com/angularPage#/Contact
http://yoursite.com/angularPage#/About
Looking at your HTML, I guessed that since you were using the # character, you did not want to use HTML5 mode, so I modified your stuff to look like this. Note how I changed the links, and your routeProvider.
<body ng-app="myApp">
<nav class='navbar navbar-default'>
<div class='container-fluid'>
<div class='navbar-header'>
<a class='navbar-header' href='Home'>Demo Site</a>
</div>
<div>
<ul class='nav navbar-nav'>
<li class='active'><a href='#Home'>Home</a></li>
<li><a href='#About'>About</a></li>
<li><a href='#Contact'>Contact</a></li>
<li><a href='#Other/Page'>Other</a></li></ul></div></div></nav>
<div ng-view></div>
</body>
JS
myApp.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(false);
$routeProvider.when("/About", {
template: '<h1>about</h1>'
})
.when("/Contact",
{
template: '<h1>Contact</h1>'
})
.when("/Other/Page",
{
template: '<h1>OtherPage</h1>'
});
});
Check the fragment syntax, and not how the routeProvider essentially parses your #Other/Page into /Other/Page. Also note the lack of a / before the links in your <a> tags, a / there means an absolute link, which would replace your current navigation tree.
Related
I'm having an issue with the ng-view not display the views when im selecting them from the nav bar. I have this installed on an IIS server, so I'm not sure if there is something I need to change their either.
Config:
angular.module('myApp.controllers').config(['$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'MainWorkQueue.html',
controller: 'MainCtrl'
})
.when('/testingQueue', {
templateUrl: 'TestingQueue.html',
controller: 'testingQueueCntl'
}).otherwise({ redirectTo: '/' });
}]);
Index.html:
<head>
<link rel="stylesheet" type="text/css" href="Content/bootstrap.css">
<script type="text/javascript" src="Scripts/angular.js"></script>
<script type="text/javascript" src="Scripts/angular-animate.js"></script>
<script type="text/javascript" src="Scripts/ui-bootstrap-tpls-2.5.0.min.js"></script>
<script type="text/javascript" src="Scripts/angular-route.js"></script>
</head>
<body ng-app="myApp.controllers">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#/">BuRT</a>
</div>
<ul class="nav navbar-nav">
<li class="active">Main Work Queue</li>
<li>Testing Queue</li>
</ul>
</div>
</nav>
<div ng-view></div>
</body>
When the page loads it loads the MainWorkQueue.html. When I select TestingQueue, the url changes, but the view doesn't.
For some reason when I run a similar code in my browser Not Using IIS it worked notice that I added on <a href=#> is now <a href=#!/> I used !/ for links in angularjs
The first when condition is true because your URL of the /testingQueue has also a /. Changing the URL for your MainWorkQueue.html for example to /main should solve your problem.
And no, the IIS is not involved.
I have a simple angualr application which have dashboard that shows the different views of items. The /dasboard/:item is an abstract state. My valid urls are /dasboard/item0/view0, /dashboard/item1/view0, etc...
I want to track the current item and current view, without the additional code and only with the help of ui-router.state variable.
This part of script
<div class="">
you are looking at <strong>{{$state.current.name}}</strong> of {{$state.$current.params.item.value()}}
</div>
is printing the current item with the current view of it. This is printing the view correctly but not the item, for which I am referring the variable $state.$current.params.item.value() , the corresponding url in browser is changing the accordingly but not the text inside the div, I don't understand what I am doing wrong here.
I am expecting the value I clicked on, but instead of that, I always get the default value of parameter, which is item0.
Here is a stripped down version of my application.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script src="https://unpkg.com/angular-ui-router/release/angular-ui-router.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myController">
<ul>
<li><a ui-sref="dashboard.view0({item: 'item0'})">item0</a></li>
<li><a ui-sref="dashboard.view0({item: 'item1'})">item1</a></li>
<li><a ui-sref="dashboard.view0({item: 'item2'})">item2</a></li>
<li><a ui-sref="dashboard.view0({item: 'item3'})">item3</a></li>
<li><a ui-sref="dashboard.view0({item: 'item4'})">item4</a></li>
</ul>
<ul>
<li><a ui-sref="dashboard.view0">view0</a></li>
<li><a ui-sref="dashboard.view1">view1</a></li>
</ul>
<div class="" ui-view>
</div>
<strong></strong>
<div class="">
you are looking at <strong>{{$state.current.name}}</strong> of {{$state.$current.params.item.value()}}
</div>
<script type="text/javascript">
angular
.module('myApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('dashboard',{
url: '/dashboard/:item',
params: {item: 'item0'},
controller: 'myController as vm',
abstract: true,
})
.state('dashboard.view0',{
url: '/view0',
templateUrl: 'view0.html',
controller: 'myController as vm'
})
.state('dashboard.view1',{
url: '/view1',
templateUrl: 'view0.html',
controller: 'myController as vm'
});
})
.run(function($rootScope, $state){
$rootScope.$state = $state;
})
.controller('myController', function($scope){
$scope.items = [{'image': '','name':'item0', 'alt': 'item0_logo'},
{'image': '','name':'item1','alt': 'item1_logo'},
{'image': '','name':'item2','alt': 'item2_logo'},
{'image': '','name':'item3','alt': 'item3_logo'}];
});
</script>
<script type="text/ng-template" id="view0.html">
<h2>This is view0</h2>
</script>
<script type="text/ng-template" id="view1.html">
<h2>This is view1</h2>
</script>
</body>
</html>
$stateParams service must be specified as a state controller, and it will be scoped so only the relevant parameters defined in that state are available on the service object.
Since your dashboard.view0 has no params, it is not showing any when you print them.
For more details see here
I am making a simple Angular application that has an index.html which loads other HTML pages as views based on which navbar item selected; however, the routing is not working as expected. The main.html view is loaded fine, but none of the other views are loaded, and the URL is not what I expect.
The URL that shows up in the browser after an item is selected is localhost:8081/#!/#pageName. I do not know where the '!' is coming from, and there should not be a hash before the pageName. The URL that I am expecting is localhost:8081/#/pageName
app.js:
'use strict';
var app = angular.module('videoGamesApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/rankedLists', {
templateUrl: 'views/rankedLists.html',
controller: 'RankedListsCtrl'
})
.when('/addGame', {
templateUrl: 'views/addGame.html',
controller: 'AddGameCtrl'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('MainCtrl', function($scope) {
$scope.message = 'THIS IS THE MAIN PAGE';
});
app.controller('RankedListsCtrl', function($scope) {
$scope.message = 'THIS IS THE RANKED LISTS PAGE';
});
app.controller('AddGameCtrl', function($scope) {
$scope.message = 'THIS IS THE ADD GAME PAGE';
});
app.controller('ContactCtrl', function($scope) {
$scope.message = 'THIS IS THE CONTACT PAGE';
});
index.html:
<!doctype html>
<html ng-app="videoGamesApp">
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../bower_components/font-awesome/css/font-awesome.css">
</head>
<body ng-controller="MainCtrl">
<header>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">GAMING </a>
</div>
<ul class="nav navbar-nav">
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-trophy"></i> Ranked Lists</li>
<li><i class="fa fa-gamepad"></i> Add a Game</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul>
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form" role="search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="sr ch-term">
<div class="input-group-btn">
<button class="btn btn-default" type="submit">
<i class="glyphicon glyphicon-search"></i>
</button>
</div>
</div>
</form>
</div>
</div>
</nav>
</header>
<div id="main">
<div ng-view=""></div>
</div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
Why are the other views not loading? Where is the exclamation point coming from in the URL? Why is there a hash before the pageName (I expect one hash, not two).
Why are the other views not loading?
The reason why your views are not loaded is because you hit the route. You use 1.6 angular and expect the behaviour from 1.5. There has been a change in location hash-prefix:
Due to aa077e8, the default hash-prefix used for $location hash-bang
URLs has changed from the empty string ('') to the bang ('!'). If your
application does not use HTML5 mode or is being run on browsers that
do not support HTML5 mode, and you have not specified your own
hash-prefix then client side URLs will now contain a ! prefix. For
example, rather than mydomain.com/#/a/b/c the URL will become
mydomain.com/#!/a/b/c.
If you actually want to have no hash-prefix, then you can restore the
previous behavior by adding a configuration block to you application:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix(''); }]); Source
What to do?
1. Set HTML5mode true
$locationProvider.html5Mode(true);
and in html set base in html header:
<base href="/">
Lastly change <a ng-href="#pagename"> to
<a ng-href="pagename">
2. Go back to old behaviour from 1.5 - set hash prefix manually
This will make your app work as you expect in your question.
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
Why is there a hash before the pageName?
The way you link is treated as a hashtag anchor tag. Which will scroll down to the current div with the given id. If you fix your problem with one of the above reasons this will be fixed aswell.
I am trying to apply some jquery in my code, but it's not working because i am using with ng-include, how can i solve this?
html:
<html lang="" ng-app="">
<head></head>
<body>
<div class="menu">
<nav class="sidebar">
<nav class="sidebar">
<div ng-include="'app/client.html'"></div>
</nav>
</nav>
</div>
<script type="text/javascript">
$(function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
});
</script>
</body>
</html>
client.html
<div class="client">
<div class="client-open">
<ul class="sidebar-nav">
<li>link1</li>
<li>link</li>
</ul>
</div>
</div>
js:
$(function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
});
Code to alter the DOM directly should go into directive.
Create a directive and attach it to the element you are trying to modify.
Plunkr - https://plnkr.co/edit/AIRb3egGSMkWfd2gpekL?p=preview
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular.js"></script>
<script data-require="jquery#3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script>
angular.module('app', [])
.directive('attachJquery', function() {
return {
restrict: 'A',
link: function (scope, element) {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
}
};
})
</script>
<style>
.tech {
color: red;
}
</style>
</head>
<body>
<div class="menu">
<nav class="sidebar">
<nav class="sidebar">
<div ng-include="'client.html'"></div>
</nav>
</nav>
</div>
</body>
</html>
client.html
<div class="client" attach-jquery>
<div class="client-open">
<ul class="sidebar-nav">
<li>link1</li>
<li>link</li>
</ul>
</div>
</div>
First proposed solution
Make sure that Jquery is loaded in your application before AngularJs.
Move the script inside client.html
Second proposed solution
Make sure that Jquery is loaded in your application before AngularJs.
Move your script into the controller as in the following example
app.controller("myCtrl", function($scope, $rootScope,$timeout) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$rootScope.$on('$includeContentLoaded', function() {
$timeout(function(){
load();
});
});
});
And then enter your function as in the following example
var load = function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
}
You can refer to this SO question for more info.
Angular: ng-include, jQuery not working unless in HTML file
One way of solving this is by creating a custom directive and adding it to div.client , then you can add your jquery code in the compile or link function of that directive.
HTML
<div class="client" load-evt>
...
</div>
Angular Directive
app.directive("loadEvt", function(){
return {
restrict: "A",
compile: function(elem){
//write your code in compile phase
},
link: function(elem, scope){
//or write your code in link phase
}
}
})
Why would you want to use jQuery and angular together?
These are 2 libraries that help you write a webapp, but go about it a VERY different way.
If you need jQuery to modify classes, you should simply use ng-class, as #fissio suggested. But in the usecase you provided, just add class="tech" to the second li. (I presume this isn't really what you wanted to know)
<div class="client">
<div class="client-open">
<ul class="sidebar-nav">
<li>link 1</li>
<li class="tech">link 2</li>
</ul>
</div>
</div>
I was following some random YT tutorial on using Angular's $routeProvider and the result - contrary to the video - is not working for me. Instead, what I get is crashed website and this error logged in Chrome's console: Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.8/$injector/modulerr?p0=site&p1=Error%3A%20…ogleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.4.8%2Fangular.min.js%3A41%3A249) By following the trail, I found that there's something wrong with `$routeProvider', but beats me if I know what. Here's my code:
var site = angular.module('site', []).
config(function($routeProvider){
$routeProvider.
when('/home', {template:'/pages/home.html'}).
when('/', {template:'/pages/home.html'}).
when('/in-play', {template:'/pages/in-play.html'}).
when('/popular', {template:'/pages/popular.html'}).
otherwise({redirectTo:'/home', tempalte:'/pages/home.html'});
});
function MainCtrl($scope, $location) {
$scope.setRoute = function(route) {
$location.path(route);
};
};
And here are all the HTMLs (I'm working with ng-include also):
<!DOCTYPE html>
<html ng-app="site">
<head>
<link rel="stylesheet" href="css/style.css">
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="scripts/app.js"></script>
<title>Pre-Demo</title>
</head>
<body ng-controller="mainStaysCtrl">
<header class="header" ng-include="'pages/header.html'"></header>
<nav class="nav" ng-include="'pages/nav.html'"></nav>
<div class="main">
<div class="left-col">
<div class="quick links" ng-include="'pages/quick_links.html'"> </div>
<div class="quick-inplay links" ng-include="'pages/quick_inplay_links.html'"></div>
<div class="winner links" ng-include="'pages/winner_links.html'"></div>
</div>
<div class="center-col" ng-controller="mainCtrl">
<div class="wraper" ng-view ng-controller="jsonCtrl"></div>
</div>
<div class="right-col">
<div class="expert-mixer" ng-include="'pages/mixer.html'"></div>
<div ng-include="'pages/twitter.html'"></div>
</div>
</div>
</body>
</html>
//included page that has the call for $routeProvider
<div class="events">
<div class="bullet">
<div class="bullet-padding">
<div ng-click="setRoute('in-play')" class="bullet-link">In-Play Links</div>
</div>
</div>
</div>
Could someone please tell me what's wrong?
EDIT
After Antiga's answer I got it to load the page. Everything besides the content that is to be loaded with ng-view and for which $routeProvider was set up in the first place. Here's the updated code:
var site = angular.module('site', ['ngRoute']).
config(function($routeProvider){
$routeProvider.
when('/home', {templateUrl:'/pages/home.html'}).
when('/', {templateUrl:'/pages/home.html'}).
when('/in-play', {templateUrl:'/pages/in-play.html'}).
when('/popular', {templateUrl:'/pages/popular.html'}).
otherwise({redirectTo:'/home', tempalteUrl:'/pages/home.html'});
});
site.controller('mainStaysCtrl', function($scope) {
$scope.setRoute = function(route) {
$location.path(route);
};
});
and HTML
<body ng-controller="mainStaysCtrl">
<header class="header" ng-include="'pages/header.html'"></header>
<nav class="nav" ng-include="'pages/nav.html'"></nav>
<div class="main">
<div class="left-col">
<div class="quick links" ng-include="'pages/quick_links.html'"></div>
<div class="quick-inplay links" ng-include="'pages/quick_inplay_links.html'"></div>
<div class="winner links" ng-include="'pages/winner_links.html'"></div>
</div>
<div class="center-col">
<div class="wraper" ng-view ></div>
</div>
<div class="right-col">
<div class="expert-mixer" ng-include="'pages/mixer.html'"></div>
<div ng-include="'pages/twitter.html'"></div>
</div>
</div>
You are not including the routing module.
Read up on this here so that you actually understand it first: https://docs.angularjs.org/api/ngRoute
Add this after you include angular.min.js:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
And then include the dependency in your main app module:
var site = angular.module('site', ['ngRoute']).
Okay, I got it working beyond Antiga's help.
There was few (yet minor) problems. I had to extend templateUrl path to include project folder.
when('/home', {templateUrl: '/ProjectName/pages/home.html', controller: 'mainStaysCtrl'}).
Other thing is that I simply forgot to include $location in controller.
site.controller('mainStaysCtrl', function($scope, $location) {
$scope.setRoute = function(route) {
$location.path(route);
};
});