I am trying to set up an angularjs application properly with separate controllers.
Using $routeProvider, I want to configure the routing in order to see different views depending on the URL.
So far it's working, but only with the view depending on the last controller loaded.
Here is the code :
Routes configuration, app.js :
'use strict';
var app = angular.module('BalrogApp', ['ngRoute', 'ui.bootstrap', 'BalrogApp.controllers']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/projectsList.html',
controller : 'projectsController',
controllerAs: 'p'
})
.when('/requests', {
templateUrl: 'views/requestsList.html',
controller : 'requestsController',
controllerAs: 'r'
})
.when('/projects', {
templateUrl: 'views/projectsList.html',
controller : 'projectsController',
controllerAs: 'p'
})
.otherwise({
redirectTo: '/lol'
});
}]);
Controller 1, requestsController.js :
'use strict';
var requestsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
requestsControllerModule.controller('requestsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Request data";
this.studentMark = 75;
});
Controller 2, projectsController.js :
'use strict';
var projectsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
projectsControllerModule.controller('projectsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Project data";
this.studentMark = 75;
});
Main html page, index.html :
<!doctype html>
<html lang="en" ng-app="BalrogApp">
<head>
<meta charset="UTF-8">
<title>Student Details App</title>
<link rel="stylesheet" href="../node_modules/angular-ui-bootstrap/ui-bootstrap-csp.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
</head>
<body>
Index page :
<ng-view></ng-view>
<!--Required JS Files List :start -->
<script src="../node_modules/angular/angular.js"></script>
<script src="../node_modules/angular/angular-route.js"></script>
<script src="../node_modules/angular-ui-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="controllers/requestsController.js"></script>
<script src="controllers/projectsController.js"></script>
<script src="js/app.js"></script>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!--Required JS Files List :end -->
</body>
</html>
HTML Requests view :
Request view :
<div class="row-fluid">
<div class="span2">{{r.studentName}} </div>
<div style="display:inline-block; min-height:290px;">
<uib-datepicker ng-model="dt" min-date="minDate" show-weeks="true" class="well well-sm" custom-class="getDayClass(date, mode)"></uib-datepicker>
</div>
</div>
HTML Projects view :
Project view :
<div class="row-fluid">
<div class="span2">{{p.studentName}} </div>
<div style="display:inline-block; min-height:290px;">
<uib-datepicker ng-model="dt" min-date="minDate" show-weeks="true" class="well well-sm" custom-class="getDayClass(date, mode)"></uib-datepicker>
</div>
</div>
So the problem there changed depending on index.html :
<script src="controllers/requestsController.js"></script>
<script src="controllers/projectsController.js"></script>
Will result in a working projects view, but not working requests view. If I include the requests controller after, this will be the opposite.
Also, is there a problem with my ControllerAs syntax ? Since I'm using it from the $routeProvider, it's not working at all.
When you do angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);, it creates a new module. What you really want is to reference an existing module, otherwise you will overwrite it every time you load a controller JavaScript file.
Change you controllers initialization to this:
angular.module('BalrogApp').controller('requestsController', function () {
// ...
});
And
angular.module('BalrogApp').controller('projectsController', function () {
// ...
});
This way, you'll be referencing an existing module and will not overwrite it every time.
In your app.js you have already defined the dependencies of modules and by defining again in the controllers you are overriding it, Fix the module line in your controllers as shown below :
Requests View :
'use strict';
var requestsControllerModule = angular.module('BalrogApp.controllers', []); // Fix This..
requestsControllerModule.controller('requestsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Request data";
this.studentMark = 75;
});
Projects view :
var projectsControllerModule = angular.module('BalrogApp.controllers', []); // Fix this..
projectsControllerModule.controller('projectsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Project data";
this.studentMark = 75;
});
Related
I have 2 html file and I want to pass parameters via angular service between them.
these are the files I have:
index.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl2">
</div>
enter here
<script>
var app=angular.module("myApp");
app.controller("myCtrl2", ['$scope','$location', 'myService',
function($scope, $location, myService) {
myService.set("world");
}]);
</script>
</body>
</html>
enter2.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl3">
hello {{x}}
</div><script type="text/javascript">
var app=angular.module("myApp");
app.controller("myCtrl3", ['$scope','$location', 'myService',
function($scope, $location, myService) {
$scope.x=myService.get();
}]);
</script>
</body>
</html>
services.js
var app=angular.module("myApp", []);
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
});
why can't I get "hello world" in enter2.html, but instead get "hello" (x is not found by service)...?
When you go from index.html to enter2.html the whole page loads from scratch. For the data that you are expecting to stay in the browser, you might need to use advanced angular concepts such as loading just a part of the page using ng-view.
If that's something you have already overruled, saving the data in the service somewhere (may be the browser session) before unloading (window.onunload event) the page and then loading it back from there when the service loads (window.onload event) could also work.
Here is a working example based on your code.
I kept your index.html and added ui-view to have a single page application. The app uses 'ui.router'.
In the myCtrl2 I saved the data in the service, and call it back from myCtrl3:
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
To keep things simple, I have one Javascript file:
angular.module('myApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'index.html',
controller: 'myCtrl2',
controllerAs: 'vm'
})
.state('enter2', {
url: '/enter2',
templateUrl: 'enter2.html',
controller: 'myCtrl3',
controllerAs: 'vm'
});
})
.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
})
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
I also uses the var vm=this and ControllerAs as often recommended to avoid $scope issues.
index.html looks like below... pleaes note the ui-sref instead of href:
<div ui-view="">
<a ui-sref="enter2">Enter here</a>
</div>
enter2.html is now just the div part and your content:
<div>
Hello {{ vm.x }}
</div>
Let us know if that helps.
Additional info:
AngularJS Routing Using UI-Router
AngularJS's Controller As and the vm Variable
Sounds like you need to use a controller for your view page
https://docs.angularjs.org/guide/controller
I am new to AngularJS and facing a problem injecting controller to an angular app. I am trying to build a single page application where the user can navigate through the pages of a particular application form. While the code for the controllers was in the same JS file, it was working fine. But moving the controllers to a separate file(as in this case, 'js/controllers/pagecontroller.js') is throwing the error below.
Error:
Uncaught Error: [$injector:nomod] http://errors.angularjs.org/1.5.5/$injector/nomod?p0=uwApp.controllers
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.5.5/$injector/modulerr?p0=uwApp&p1=Error%3A%2…oogleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.5%2Fangular.min.js%3A21%3A19)
index.html:
<!DOCTYPE html>
<html ng-app="uwApp">
<head>
<!-- SCROLLS -->
<!-- load bootstrap and fontawesome via CDN -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.css" />
<!-- SPELLS -->
<!-- load angular and angular route via CDN -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-route.js"></script>
<!-- Donut chart api -->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="js/app.js"></script>
<script src="js/controllers/maincontroller.js"></script>
<script src="js/controllers/pagecontroller.js"></script>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body ng-controller="mainController">
<div ng-view></div>
</body>
</html>
app.js
'use strict';
var uwApp = angular.module('uwApp', ['uwApp.controllers','ngRoute'])
.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the page
.when('/acknandagreement', {
templateUrl : 'pages/loan/acknandagreement.html',
controller : 'pageCtrl9'
})
// route for the page
.when('/assetsandliabilities', {
templateUrl : 'pages/loan/assetsandliabilities.html',
controller : 'pageCtrl6'
})
// route for the page
.when('/borrowerinfo', {
templateUrl : 'pages/loan/borrowerinfo.html',
controller : 'pageCtrl3'
})
// route for the page
.when('/employmentinfo', {
templateUrl : 'pages/loan/employmentinfo.html',
controller : 'pageCtrl4'
})
// route for the page
.when('/infoandgovpurpose', {
templateUrl : 'pages/loan/infoandgovpurpose.html',
controller : 'pageCtrl10'
})
// route for the page
.when('/monthlyincomeandche', {
templateUrl : 'pages/loan/monthlyincomeandche.html',
controller : 'pageCtrl5'
})
// route for the page
.when('/morttypeandterm', {
templateUrl : 'pages/loan/morttypeandterm.html',
controller : 'pageCtrl1'
})
// route for the page
.when('/propertyinfoandpurpose', {
templateUrl : 'pages/loan/propertyinfoandpurpose.html',
controller : 'pageCtrl2'
})
// route for the page
.when('/residualapplication', {
templateUrl : 'pages/loan/residualapplication.html',
controller : 'pageCtrl11'
})
// route for the page
.when('/txndetails', {
templateUrl : 'pages/loan/txndetails.html',
controller : 'pageCtrl7'
})
// route for the page
.when('/declarations', {
templateUrl : 'pages/loan/declarations.html',
controller : 'pageCtrl8'
})
;
});
pagecontroller.js:
'use strict';
angular.module('uwApp.controllers')
.controller('pageCtrl1', function($scope) {
$scope.page = 'morttypeandterm';
})
.controller('pageCtrl2', function($scope) {
$scope.page = 'propertyinfoandpurpose';
})
.controller('pageCtrl3', function($scope) {
$scope.page = 'borrowerinfo';
})
.controller('pageCtrl4', function($scope) {
$scope.page = 'employmentinfo';
})
.controller('pageCtrl5', function($scope) {
$scope.page = 'monthlyincomeandche';
})
.controller('pageCtrl6', function($scope) {
$scope.page = 'assetsandliabilities';
})
.controller('pageCtrl7', function($scope) {
$scope.page = 'txndetails';
})
.controller('pageCtrl8', function($scope) {
$scope.page = 'declarations';
})
.controller('pageCtrl9', function($scope) {
$scope.page = 'acknandagreement';
})
.controller('pageCtrl10', function($scope) {
$scope.page = 'infoandgovpurpose';
})
.controller('pageCtrl11', function($scope) {
$scope.page = 'residualapplication';
});
maincontroller.js
'use strict';
angular.module('uwApp.controllers', [])
.controller('mainController', function($scope) {
});
I have no clue why its not working. Please suggest.
In pageController.js write like this
angular.module('uwApp.controllers', [])
.controller('mainController', function($scope) {
$scope.page = 'main controller';
})
some Explanation:
Beware that using angular.module('myModule', []) will create the module myModule and overwrite any existing module named myModule. Use angular.module('myModule') to retrieve an existing module.
Find more angular docs module
There is an interesting style guidelines for angular by jonpapa johnpapa/angular-styleguide
Update
I made a working example on plnkr from supplied code. There are a couple things I changed:
1) Since your base route will be running mainController you should not put it on the ng-controller as well.
2) When you are referencing a module, as in the angular.module('uwApp.controllers'), the module must first have been defined. The way to define a module is to have brackets for it's dependencies, like angular.module('uwApp.controllers', []).
With those things fixed you do not need to do what I said below.
There is no need to inject the controllers through a separate module.
You can change pagecontroller.js:
angular.module('uwApp.controllers')
to...
angular.module('uwApp')
Then app.js:
var uwApp = angular.module('uwApp', ['uwApp.controllers','ngRoute'])
to...
var uwApp = angular.module('uwApp', ['ngRoute'])
I have an issue were my routing is not populating my view.
I have the following code running from an Xampp local server:
angular 1.4.9
index.html:
<html>
<head>
<script src="scripts/angular.js" type="javascript/text"></script>
<script src="scripts/Ng-Route.js" type="javascript/text"></script>
<script src="scripts/app.js" type="javascript/text"></script>
</head>
<body ng-app="myApp">
<div ng-view></div>
</body>
</html>
user.html:
<div>
<fieldset>
Hello, {{ctrl.message}}
</fieldset>
</div>
app.js:
var app = angular.module('myApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'user.html',
controller : 'controller as ctrl'
});
$routeProvider.otherwise({ redirectTo: '/' });
});
app.controller('controller', function() {
var self = this;
self.message = 'Everyone';
});
I have absolutely no clue why this is failing, nothing shows up on the page. I am expecting "Hello, Everyone".
Any help would appreciated.
You had mistaken declaring your controller on your route. controller does accept controller name in string/controller function. And use controllerAs option to alias your controller.
$routeProvider
.when('/', {
templateUrl : 'user.html',
controller : 'controller',
controllerAs: 'ctrl'
});
I am just setting up a simple Angular app as I've done countless times. I added a home state and a separate state for a note taking app, yet neither states are displaying/injecting the html partials into the ui-view. I think it might be an issue with my ui-router setup, but I cannot find the issue. I console log from my controllers and they trigger correctly, so the states are clearly pointing to the right controllers.
Index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
<script src="bower_components/angular/angular.js"></script>
<script src="node_modules/angular-ui-router/release/angular-ui-router.js"></script>
<script src="app.js"></script>
<script src="factory.js"></script>
<script src="config.js"></script>
</head>
<body ng-app="myApp">
<ui-view></ui-view>
</body>
</html>
config
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateURL: './home.html',
controller: 'homeCtrl'
})
.state('list', {
url: '/list',
templateURL: '/list.html',
controller: 'listCtrl'
})
$urlRouterProvider.otherwise('/home');
});
app.js
'use strict';
var app = angular.module('myApp', ['ui.router']);
app.controller('listCtrl', function($scope, myFactory) {
console.log("list working!");
$scope.items = myFactory.items
$scope.addItem = function() {
$scope.items.unshift($scope.newItem);
$scope.newItem = "";
}
})
app.controller('homeCtrl', function($scope) {
console.log("home working!");
$scope.test = 'test'
})
My home state should load a partial containing:
<div>
<h1>Welcome!</h1>
</div>
Plunker
http://plnkr.co/edit/ngHYDtx0VBe2YPlBeJ3t?p=preview
It has to be
templateUrl: './home.html',
Also, it is not desirable to use relative paths for templates, './home.html' and 'home.html' will be cached internally as two different templates.
I have this project structure :
-root
|-JS
|-app.js
|-COMPONENTS
|-HOME
|-homeController.js
|-homeView.html
|-ERROR
|-error.html
|-index.html
Here is index.html:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- JS LOADING -->
<script src="./bower_components/angular/angular.js"></script>
<script src="./bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<!--APP JS -->
<script src="js/components/app.js"></script>
<script src="./js/shared/services/lb-service.js"></script>
<!--HOME JS-->
<script src="./js/components/home/homeController.js"></script>
</head>
<body ng-app='benirius'>
<ul class="nav navbar-nav">
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="error">Error</a></li>
</ul>
<div ui-view></div>
</body>
</html>
and app.js:
'use strict';
angular.module('benirius', [
'lbServices',
'ui.router'
])
.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: '/components/home/homeView.html',
controller: 'homeController'
})
.state('error', {
url: '/error',
templateUrl: '/components/error/error.html'
});
$urlRouterProvider.otherwise('/');
}]);
edit adding homeController.js:
angular.module('benirius',[])
.controller('homeController', ['$scope', function($scope) {
$scope.test = "Inside home.";
}]);
Angular ui router does not create links / load pages.
All js files are loaded and no javascript error shown in console.
Does someone know why ui-router is not working ?
Ps : I've been playing around with templateUrl path with no success.
As show here in angular doc, when you separate files and add controllers, services, or others to a module, you have to load it with no arguments.
You first define your app in a file :
angular.module('benirius', [
'lbServices',
'ui.router'
])
.config(
// CODE IN HERE
);
$urlRouterProvider.otherwise('/');
}]);
Then if you want to add elements to your app in another file, you load the module with no arguments, like this:
// notice there is no second argument therefore it loads the previously defined module 'benirius'
angular.module('benirius')
.controller('homeController', ['$scope', function($scope) {
$scope.test = "Inside home.";
}]);
//=> NO ERROR
instead of:
// In this case, it is considered as a redefinition of 'benirius' module with no dependencies injected
angular.module('benirius',[])
.controller('homeController', ['$scope', function($scope) {
$scope.test = "Inside home.";
}]);
//=> ERROR