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.
Related
Do the newest versions of angular/angular-route 1.6.1 use hashbang by default? Take this piece of code for example, I have to use #! when linking to partials because #/ or #/partial2 does not work. I thought that you'd have to set a hash prefix but it looks like it's defaulting to that behavior:
<!DOCTYPE html>
<html ng-app='myApp'>
<head>
<title></title>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-route/angular-route.js"</script>
<script>
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/',{
templateUrl: 'partials/view1.html',
})
.when('/partial2',{
templateUrl: 'partials/view2.html'
})
.otherwise({
redirectTo: '/'
});
});
myApp.controller('view1Controller', function ($scope) {
$scope.sports = ['golf', 'basketball', 'hockey', 'tennis', 'football'];
});
myApp.controller('view2Controller', function ($scope) {
$scope.message = 'We are using another controller';
});
</script>
</head>
<body>
<div ng-app='myApp'>
Partial 1 | Partial 2
<div ng-view="">
</div>
</div>
</body>
</html>
Starting angular 1.6.0, #!/ becomes defaults in routes. I basically worked down versions until #/ worked, which was 1.5.11.
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 have set up a basic AngularJS app in VS and cannot get the ui-router functionality working. I have looked at videos, blogs, SO answers and as far as I can tell I am doing everything right, although, I am brand new to web development.
First, here is the solution structure:
and the code...
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<meta charset="utf-8" />
</head>
<body ng-app="app">
<div ui-view></div>
<script src="bower_components/angular/angular.js"></script>
<script src="app/app.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
</body>
</html>
app.js:
(function () {
'use strict';
angular.module('app', ['ui.router']);
})();
app.states.js:
(function () {
'use strict';
angular.module('app')
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/test.html',
controller: 'testCtrl',
controllerAs: 'vm'
})
});
})();
test.html:
<div>
<p>TEST PAGE</p>
</div>
testCtrl.js:
(function () {
'use strict';
angular.module('app')
.controller('testCtrl', testCtrl);
testCtrl.$inject = ['$state'];
function testCtrl($state) {
var vm = this;
var userAuthenticated = false;
init();
function init() {
$state.go('home');
};
};
})();
Can anyone see anywhere I have made a mistake?
There is a working example
I would say, that I miss these lines in your index.html
...
<script src="app/app.states.js"></script>
<script src="templates/testCtrl.js"></script>
That will loade the crucial state definition, and related controller. Check it in action here
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
Let's say I have two pages, cloud and settings. I have the following code set up:
var routerApp = angular.module('APP', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/cloud');
$stateProvider
.state('cloud', {
url: '/cloud',
templateUrl: 'pages/templates/cloud.html',
controller: 'cloud',
})
.state('settings', {
url: '/settings',
templateUrl: 'pages/templates/settings.html',
controller: 'settings'
});
});
routerApp.controller('cloud', function($scope, $http, $state) {
alert("cloud");
});
routerApp.controller('settings', function($scope, $http, $state) {
alert("settings");
});
HTML
<!DOCTYPE html>
<html lang="en" ng-app="APP">
<head>
<title>TITLE</title>
<base href="/">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.min.js"></script>
<script src="/js/app.js" type="text/javascript"></script>
</head>
<body>
<div id="navContainer">
<a ui-sref="cloud">Cloud</a>
<a ui-sref="settings">Settings</a>
</div>
<div id="pageContent">
<div ui-view></div>
</div>
</body>
</html>
Regardless of what page I load, settings or cloud, the each controller will run no matter what. Meaning I will get 2 alerts, regardless, when I reload the page.
Could anyone help explain what I need to do so that if I reload my website on /settings, only the code in my settings controller will run and vice versa?
If you have your controllers declared in the partials(views) that your router is loading then those controllers will only fire when the view is loaded. It sounds to me like you need a parent controller(s) that will fire to give you logic that can controller both of the views.
Your Code:
$stateProvider.state('cloud', {
url: '/cloud',
templateUrl: 'pages/templates/cloud.html',
controller: 'cloud',
})
.state('settings', {
url: '/settings',
templateUrl: 'pages/templates/settings.html',
controller: 'settings'
});
You are setting the controllers there if you would like them to share a controller simply refer to the same controller like so:
$stateProvider
.state('cloud', {
url: '/cloud',
templateUrl: 'pages/templates/cloud.html',
controller: 'shared',
})
.state('settings', {
url: '/settings',
templateUrl: 'pages/templates/settings.html',
controller: 'shared'
});