Having an issue using the ng-view to render a template from my controller.
The index.html file is initially served to the client and looks like.
<!doctype html>
<html lang="en" ng-app="hlmApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title></title>
<link rel="stylesheet" href="#Model.Root.Resource/bower_components\\/bootstrap/dist/css/bootstrap.css">
#RenderSection("BootScript")
<!-- app.js will load the angular module -->
<script src="#Model.Root.Resource/bower_components/angular/angular.js"></script>
<script src="#Model.Root.Resource/bower_components/angular-route/angular-route.js"></script>
<script src="#Model.Root.Resource/app/app.js"></script>
<script src="#Model.Root.Resource/app/controllers/controllers.js"></script>
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<li>A link here</li>
</ul>
</div>
</div>
<div ng-view></div>
#*<div ng-controller="tempController">{{Heading}}</div>*#
</div>
#RenderBody()
</body>
</html>
the server pushes down my app.js and controllers.js file along with the deps.
/// ap.js ///
var hlmApp = angular.module('hlmApp', ['ngRoute', 'MyTempControllers']);
hlmApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/Holdings', {
templateUrl: 'templates/temp.html',
controller: 'controllers/tempController'
});
}]);
the controller is pretty simple and is as follows
var MyTempControllers = angular.module('MyTempControllers', []);
MyTempControllers.controller('tempController', ['$scope', function () {
console.log("stuff happening");
$scope.Heading = "Hello World";
}]);
then the html template is as follows
<div>
<h3>{{Heading}}</h3>
</div>
When I use the ng-view nothing ever renders. the controller is never triggered in the debugger. If I specifically call out the controller via the ng-controller then everything shows up. can someone point out my error here?
You need these 3 changes:
1) add $scope as a parameter in your controller function
MyTempControllers.controller('tempController', ['$scope', function ($scope) {
...
}]);
2.
Change
controller: 'controllers/tempController'
to
controller: 'tempController'
FYI, the naming convention for a controller is to begin with a capital letter for Controller.
3. In addition, you should add a
.otherwise({
template: templates/temp.html,
controller: 'tempController'
});
so that when no route matches, it goes to default-page-name.html. This is what's happening in your case, when you first load the page, no route matches. If you want to see temp.html, you have to 1) either click on a link that goes to #/Holdings, or 2) use '/Holdings' as the "otherwise" route, as indicated above.
Try this:
hlmApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/Holdings', {
templateUrl: 'templates/temp.html',
controller: 'tempController' // just the name
});
}]);
and also $scope is missing in parameters:
MyTempControllers.controller('tempController', ['$scope', function ($scope) {
console.log("stuff happening");
$scope.Heading = "Hello World";
}]);
Related
I'm creating a website and I'm using JavaScript + AngularJS, presently I create the routes for the application, but it always returns 404 not found on the server, I've tried several examples of the internet but none of them worked, here's an example of my code, remembering that The html pages are inside the WebContent:
<html ng-app="angularRoutingApp">
<head>
<title>Home</title>
<meta charset="utf-8">
</head>
<body>
<div>
index <br> home
</div>
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.3/angular-route.js"></script>
<script>
var angularRoutingApp = angular.module('angularRoutingApp', ['ngRoute']);
angularRoutingApp.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when("/index", {
template: "/index.html"
})
.otherwise({
redirectTo: '/home.html'
});
});
</script>
</body>
</html>
you forgot the ng-view directive.
also,
the href need to be with a hash prefix - or using the Link directive.
the redirectTo key need to provide a view [name/address] & not a
template
if you want to use template files & not inline code use the templateUrl key
you can see an example of your code here: http://codepen.io/AceDesigns/pen/ZLXLKa
<html ng-app="angularRoutingApp">
<head>
<title>Home</title>
<meta charset="utf-8">
</head>
<body>
<div>
index<br>
home
</div>
<div class="">
<ng-view></ng-view>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.3/angular-route.js"></script>
<script>
var angularRoutingApp = angular.module('angularRoutingApp', ['ngRoute']);
angularRoutingApp.config(function($routeProvider){
$routeProvider
.when("/index", {template:"<div>INDEX VIEW</div>"})
.when("/home", {template:"<div>HOME VIEW</div>"})
.when("/tempFile", {templateUrl: "views/temp_file.html"})
.otherwise({redirectTo: '/home'});
});
</script>
</body>
</html>
I have had a look through SO and nothing has helped.
This is my app.js
var app = angular.module("qMainModule", ["ngRoute"])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: 'templates/anonHome/anonHome.html',
controller: 'templates/anonHome/anonHomeController'
})
.when("/about", {
templateUrl: 'templates/anonHome/anonAbout.html',
controller: 'templates/anonHome/anonAboutController'
})
.when("/services", {
templateUrl: 'templates/anonHome/anonServices.html',
controller: '/templates/anonHome/anonServicesController'
})
.when("/contact", {
templateUrl: 'templates/anonHome/anonContact.html',
controller: '/templates/anonHome/anonContactController'
})
.when("/register", {
templateUrl: 'templates/anonHome/anonRegister.html',
controller: '/templates/anonHome/anonRegisterController'
})
.when("/login", {
templateUrl: 'templates/anonHome/anonLogin.html',
controller: '/templates/anonHome/anonLoginController'
})
$locationProvider.html5Mode(true);
})
app.controller("qMainController", function ($scope) {
$scope.Title = " Welcome to Qiao";
$scope.qNavigationTemplatePath = "/templates/topMenu/anonTopNavigation.html";
$scope.copyrightMessage = "Qiao ";
$scope.copyrightYear = new Date();
});
The routing works as expected and the partial templates are being shown but the partial templates controllers are not being recognised as a function.
The Layout Template looks like this
<!DOCTYPE html>
<html ng-app="qMainModule">
<head ng-controller="qMainController">
<base href="/" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Qiao :: {{Title}}</title>
<!-- Bootstrap Core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="../css/modern-business.css" rel="stylesheet" />
<!-- Custom Fonts -->
<link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="/scripts/angular.js"></script>
<script src="../scripts/angular-route.js"></script>
<script src="/app/app.js"></script>
<script src="templates/anonHome/anonHomeController.js"></script>
<!-- <link href="../styles/qiao.css" rel="stylesheet" /> -->
</head>
<body ng-controller="qMainController">
<div ng-include="qNavigationTemplatePath">
</div>
<!-- Page Content -->
<div class="container">
<ng-view></ng-view>
</div>
<!-- Footer -->
<footer>
<div class="row">
<div class="col-lg-12" ng-controller="qMainController">
Copyright © {{copyrightMessage}} {{copyrightYear | date:'yyyy'}}
</div>
</div>
</footer>
<div >
<!-- jQuery -->
<script src="js/jquery.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="js/bootstrap.min.js"></script>
<!-- Script to Activate the Carousel -->
<script>
$('.carousel').carousel({
interval: 5000 //changes the speed
})
</script>
</div>
</body>
</html>
The partial template looks like this:
<script src="anonHomeController.js"></script>
<div ng-controller="anonHomeController">
<h1>{{Title}}</h1>
</div>
and its controller is this
function anonHomeController($scope) {
$scope.Title = " Welcome to Qiao";
$scope.qNavigationTemplatePath = "/templates/topMenu/anonTopNavigation.html";
$scope.copyrightMessage = "Qiao ";
$scope.copyrightYear = new Date();
};
The Question: How do I get Angular to recognise and use the partial template's controller?
While defining a controller, don't use any directory paths.
From the docs - https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
controller – {(string|Function)=} – Controller fn that should be associated with newly created scope or the name of a registered controller if passed as a string.
Note that the registered controller never has the entire path, it is the function definition itself or the function's name (a string). You may need module names, if you have exported like that, but that's different from a directory path.
All you need is just use <script> tags in index.html, which will include all your functions. Now if your functions are just plain javascript, and you don't intend using angular.module('app').controller there, use it in the app.js, Just angular.module('app').controller('anonHomeController', anonHomeController); Note that your definition can still remain in the Javascript file /some/path/totemplate/anonHomeController.js. I suggest you try that and see if it works.
app.js
app.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: 'templates/main/main.html',
controller: 'MainCtrl'
})
index.html
<script src="controllers.js"></script>
controllers.js
function MainCtrl ($scope) {
$scope.name = 'World';
}
A working plnkr here
You have created your controller for each view as a regular JS function, which is incorrect. It should be like
app.controller("anonHomeController", function ($scope) {
$scope.Title = " Welcome to Qiao";
// rest of the controller code
});
and the file should be anonHomeController.js at the path you have defined in the config. you also do not need to include the scipt tag in the header of the view. Check for some example here
You don't need to add complete path in your app.js for defining controllers.
If you're controllers are defined in the same file, then this should do the job:
$routeProvider
.when("/", {
templateUrl: 'templates/anonHome/anonHome.html',
controller: 'xyzController'
});
app.controller("xyzController", function ($scope) {
// controller function here
});
If you want your controllers to be in an external file, you'll have to do the following:
1. Define the controllers module:
angular.module('app.controllers', [])
.controller("homeController", function(){....})
Name this file as controllers.js
2. Now your main app.js should include this:
angular.module('app', [
'app.controllers',
])
Include controllers.js in your main html file
I have a header which remains common for all the pages. So, I included it in my index page like this.
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="assets/lib/angular.js"></script>
<script src="assets/lib/angular-route.js"></script>
<script src="headerController.js"></script>
<script src="HomeController.js"></script>
<script src="app.js"></script>
</head>
<body>
<div class="header" ng-include="'header.html'"></div>
<div class="main" ng-view></div>
</body>
</html>
header.html
<ul>
<li>{{vm.myName}}"></li>
</ul>
My app.js file looks like this.
( function () {
angular.module('myApp', [
'ngRoute',
'myApp.header',
'myApp.home',
])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/home', {
controller: 'HomeController',
templateUrl: 'homeView.html',
controllerAs: 'vm'
})
.otherwise({
redirectTo: '/home'
});
}]);
})();
I'm not including home controller or view as they have less importance here now. What I'm trying to do is, to pass a value from headerController.js to it's view header.html
As you can see, there is only one variable in my header.html
On the other side, headerController.js communicates with a backend service and fetches this result. And, I'm sure data is being returned by the service, I can see it in console and it looks like this:
{"myName":"Amelia Earheart"}
and here is my headerController.js
(function() {
angular
.module('myApp.header', [])
.factory('myCommonService', function($http) {
var baseUrl = 'api/';
return {
getName:function() {
return $http.get(baseUrl + 'getName');
}
};
})
.controller('CommonController', function($scope, $routeParams, myCommonService) {
var vm = this;
myCommonService.getName().success(function(data) {
vm.myName = data.myName;
});
});
})();
Can anyone tell why I am not getting the value in html view?
You should link your view with your controller.
Actually, your CommonController is not referenced anywhere. Try adding a ng-controller attribute to the div.header :
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="assets/lib/angular.js"></script>
<script src="assets/lib/angular-route.js"></script>
<script src="headerController.js"></script>
<script src="HomeController.js"></script>
<script src="app.js"></script>
</head>
<body>
<div class="header" ng-controller="CommonController" ng-include="'header.html'"></div>
<div class="main" ng-view></div>
</body>
</html>
And also you need to bind the value to the $scope (which is your model) rather to this. Your controller should look like this :
.controller('CommonController', function($scope, $routeParams, myCommonService) {
myCommonService.getName().success(function(data) {
$scope.myName = data.myName;
});
});
If you want to use "vm" in your header's view, you can change the ng-controller to ng-controller="CommonController as vm". This should do the trick.
If you don't do this, you'll have to update your header.html to :
<ul>
<li>{{myName}}</li>
</ul>
I would like to have a link back to the landing page in the header of my app's views but obviously not on the landing page itself. How would I optimally implement that in Angular.js?
Should I use $location.url() to determine the view or should I use bind-html or something else altogether?
Thanks for some tips and help!
EDIT
my current code, I thought I'd made it a little easier since each view has its own controller, however the link is always shown:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<style>
</style>
</head>
<body ng-app="myApp">
<div data-role="page" id="pageone">
<div data-role="header">
<h1>WELCOME!</h1>
BACK TO HOME
</div>
<div ng-view></div>
<div data-role="footer">
<h1>footer</h1>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.min.js"></script>
<script>
'use strict';
var app = angular.module('myApp', ['ngRoute']);
app.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
$routeProvider
.when('/', {
templateUrl : 'views/home.html',
controller : 'HomeController'
})
.when('/other', {
templateUrl : 'views/other.html',
controller : 'OtherController'
});
});
app.controller('HomeController', function($scope, $http, $location, $route) {
$scope.isLandingPage = true;
});
app.controller('OtherController', function($scope, $route) {
$scope.info = 'Other';
});
</script>
</body>
</html>
The link is always shown because your div in which is link doesn't have any controller attached.
You can do it this way:
app.controller('landingPageCtrl', ['$scope', '$location', function($scope, $location){
$scope.isLandingPage = function(){
return ($location.url() == '/home') ? true : false;
}
}]);
then use ng-show to hide or show link depending on location
<div ng-controller="landingPageCtrl" data-role="header">
<h1>WELCOME!</h1>
BACK TO HOME
</div>
I like to check for my route (or state in ui.router).
$scope.isLandingPage = $state.current.name === 'home';
and use <a ng-show="!isLandingPage">Link</a>
For some reason I cannot retrieve the data from my controllers scope variables in my views. All of my views use the same controller, so I am not sure what went wrong. Any help would be appreciated.
Here is my App.js
var app = angular.module('app', [
'ngRoute'
]);
// Route configurations
app.config(['$routeProvider', function ($routeProvider){
$routeProvider.when('/', {
templateUrl: 'partials/home.html',
controller: 'MainController'
})
.when('/countries', {
templateUrl: 'partials/countriesList.html',
controller: 'MainController'
})
.when('/details', {
templateUrl: 'partials/countryDetails.html',
controller: 'MainController'
})
.otherwise({
redirectTo: '/'
});
}]);
// Main Controller Setup
app.controller('MainController', ['$scope', MainController]);
function MainController ($scope){
$scope.hello = 'hello';
}
Here is one of the view I am trying to access the scope in:
<h1>Country List</h1>
<button class="btn">Countries Details</button>
<p>hello: {{hello}}</p>
Here is my index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Countries and Capitals</title>
<link rel="stylesheet" type="text/css" href="css/vendor/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body ng-controller="MainController" ng-cloak>
<div class="container">
<div class="row">
<div class="col-sm-12 text-center">
<ng-view></ng-view>
</div>
</div>
</div>
<script src="js/vendors.js"></script>
<script src="js/scripts.js"></script>
</body>
</html>
The problem because of nested scopes. The better way use some nested scopes is use controllerAs method. Could you try:
```
<body ng-controller="MainController as myctrl" ng-cloak>
<p>hello: {{myctrl.hello}}</p>
```
What you do while adding a controller in ng-route is you create another scope of the same controller. My suggestion is you use either no controller i.e. remove controller attribute or add $parent. in the view you are referencing.
The first one is preferred if u want to have same scope over a set of pages, the second one is preferred when u have different controllers for different pages.
Along with that if u want to access global variables, u can add them to $rootScope and access them globally..
Hope this helps