I'm new to angularjs and just started working on a project
I'm using ui.router for managing different views
the problem im facing is that i have a master page index.html for example
<html lang="en" ng-app="leadsangularApp">
<head>
<link href="style1.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div ui-view=""></div>
</body>
</html>
all my views load in
<div ui-view=""></div>
but what if i have a login page that has completely different css styles(head) and js files(footer) i need it to load inside different template, example
<html lang="en" ng-app="leadsangularApp">
<head>
<link href="style2.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div ui-view=""></div>
</body>
</html>
if i try to do it with nested ui-view
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
// States
$stateProvider
.state('root', {
abstract: true,
templateUrl: 'views/default.html',
})
.state('home', {
parent: "root",
url: "/home",
templateUrl: 'views/main.html',
})
.state('login', {
url: "/login",
templateUrl: 'views/login.html',
});
});
my /login page has different view but still it loads the same css and js files
i want my /login page to have completely different head section and footer section, how do i achieve that?
Generally speaking this is not a recommended approach, but there is a github project that does this for css: https://github.com/manuelmazzuola/angular-ui-router-styles. It's not something directly supported by ui-router.
You can use ng-href. And depending on your needs, you will have to listen to $stateChangeSuccess and change the values that is binded to ng-href.
For your HTML, do something like this:
<link rel="stylesheet" ng-href="{{stylesheet}}" />
where the variable stylesheet is dynamically binded to your scope, and can change values according to your needs.
Then you can either listen to $stateChangeStart or $stateChangeSuccess and change the $scope.stylesheet values accordingly.
app.controller('mainCtrl', function($scope, $state) {
$scope.stylesheet = "style.css";
$scope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
if (toState.name === "login") {
$scope.stylesheet = "style2.css"
} else {
$scope.stylesheet = "style.css"
}
})
})
Here is the plnkr: http://plnkr.co/edit/qR7FLDAyRTkFndMQyWod?p=preview
To read more about ui-router's API: http://angular-ui.github.io/ui-router/site/#/api/ui.router.state
Related
I'm working on a small project and it's been a while since I've worked with Angular. I'm trying to separate all my templates/controllers so I don't have one gigantic file, but I want to be able to access them all on the one page. I'm using Angular UI router, and trying to have them all load on the same route. It doesn't seem to work. Does anyone have any idea how I can load everything on one route but still keep everything separate? Currently it's only loading the first controller/template listed in my routing file (createCompanyController) and not the others.
Here is my routes.js file:
(function() {
angular.module('myApp', ['ui.router'])
.config(['$stateProvider', function($stateProvider) {
var applicationStates = [{
name: 'homepage',
url: '/app',
templateUrl: 'partials/CreateCompany/createCompany.html',
controller: 'createCompanyController',
controllerAs: 'createCompanyCtrl'
},
{
name: 'guestbook',
url: '/app',
templateUrl: 'partials/CreatePerson/createPerson.html',
controller: 'createPersonController',
controllerAs: 'createPersonCtrl'
},
{
name: 'states',
url: '/app',
templateUrl: 'partials/ListCompanies/listCompanies.html',
controller: 'listCompaniesController',
controllerAs: 'listCompaniesCtrl'
}];
applicationStates.forEach(function(state) {
$stateProvider.state(state);
});
}])
})();
And the index.html file I'm using:
<html ng-app='myApp'>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.css'/>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link href='app.less' type='text/css' rel='stylesheet/less'>
</head>
<body class="container" ng-cloak>
<div class='row'>
<div class='span12'>
<div ui-view></div>
</div>
</div>
</body>
</html>
(All my script tags are there, I just removed them from this post to make space). If anyone can help me out I'd be very grateful.
You can use Multiple Named Views
$stateProvider.state('app', {
url: '/app',
views: {
'': {
templateUrl: 'home/home.html'
},
'homepage#app': {
name: 'homepage',
templateUrl: 'partials/CreateCompany/createCompany.html',
controller: 'createCompanyController',
controllerAs: 'createCompanyCtrl'
},
'guestbook#app': {
name: 'guestbook',
templateUrl:'partials/CreatePerson/createPerson.html',
controller: 'createPersonController',
controllerAs: 'createPersonCtrl'
},
'states#app': {
name: 'states',
templateUrl:'partials/ListCompanies/listCompanies.html',
controller: 'listCompaniesController',
controllerAs: 'listCompaniesCtrl'
}
}
And the index.html
<html ng-app='myApp'>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.css'/>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link href='app.less' type='text/css' rel='stylesheet/less'>
</head>
<body class="container" ng-cloak>
<div class='row'>
<div class='span12'>
<div ui-view="homepage"></div>
<div ui-view="guestbook"></div>
<div ui-view="guestbook"></div>
</div>
</div>
</body>
</html>
The answer to your question is "Angular Components" (available from angular 1.5 version onward).
Component => Template + Controller
Angular Route which would contain all templates => combination of components (in your case CreateCompany, CreatePerson and ListCompanies components all in one route's template)
All you need to do is:
Create components (controller + template for CreateCompany, CreatePerson and ListCompanies) instead of routes.
Create a single route "/app" and define the template for this route as below
HomePage.html
<div class='row'>
<div class='span12'>
<create-company></create-company>
<create-person></create-person>
<list-companies></list-companies>
</div>
</div>
Fiddle: https://jsfiddle.net/vuas3wbq/2/
Reference link for Angular components:
https://docs.angularjs.org/guide/component
I was following these instructions here and cannot get this to work.
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
I verified my bootstrap grid divs work by putting them all in index.html and loading the page. Then I "angularfied' it, and the page doesn't render.
I don't see any errors in the javascript console.
To start out with, the page is supposed to look like this. Actual screen shot of the webpage before I split out the views from index.html
Here is my code after I added angular and created multiple views:
index.html
<html ng-app="stackoverflowApp">
<head>
<meta charset="utf-8"/>
<title>stackoverflow Question</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css" type="text/css"/>
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="scripts/stackoverflowApp.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div ui-view="stackoverflowTopPane"/>
</div>
<!-- main panel-->
<div class="row">
<!-- Left pane-->
<div ui-view="stackoverflowLeftPane"></div>
<!-- content pane-->
<div ui-view="stackoverflowMainPane"></div>
</div>
</div>
</body>
</html>
js
'use strict';
angular.module('stackoverflowApp', [
'ui.router'
])
.run(
['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}
]
)
.config(
['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
/////////////////////////////
// Redirects and Otherwise //
/////////////////////////////
$urlRouterProvider
.otherwise('/');
//////////////////////////
// State Configurations //
//////////////////////////
// Use $stateProvider to configure your states.
$stateProvider
//////////
// Home //
//////////
.state("home", {
views: {
'stackoverflowTopPane': {
templateUrl: 'so-views/stackoverflow-top-pane.html'
},
'stackoverflowLeftPane': {
templateUrl: 'so-views/stackoverflow-left-pane.html'
},
'stackoverflowMainPane': {
templateUrl: 'so-views/stackoverflow-main-pane.html'
}
}
})
}
]
);
As far as I can see, you never assign the "home" state the index.html URL. Try setting url: "/", just before "views"
So, today I added angular-ui-router to my webapp. However, it's showing some really weird behaviour. It used to display the current page in the ui-view. So a page in a page.
Now, it's working correct, but it doesn't show subpages and I can't seem to figure out why.
Main page
<!doctype html>
<html lang="en" ng-app="ExampleApp">
<head>
<meta charset="UTF-8">
<title>Example App</title>
</head>
<body>
<div>
<div ui-view></div>
</div>
<!-- Angular -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js"></script>
<!-- UI-Router -->
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<!-- Main app file -->
<script src="/js/main.js"></script>
</body>
</html>
main.js
var ExampleApp = angular.module('ExampleApp', ['ui.router']);
ExampleApp.config(function($stateProvider, $urlRouterProvider) {
//
// For any unmatched url, redirect to /home
$urlRouterProvider.otherwise("/home");
//
// Now set up the states
$stateProvider
.state('home', {
url: "/home",
templateUrl: "views/home.html",
controller: "MainController"
})
.state('settings', {
url: "/settings",
templateUrl: "views/settings.html",
controller: "SettingsController"
})
.state('settings.account', {
url: "/account",
templateUrl: "views/settings.account.html",
controller: "AccountSettingsController"
});
});
ExampleApp.config(["$locationProvider", function($locationProvider) {
$locationProvider.html5Mode(true);
}]);
Try this
url:"settings/account",
I have a drill down from one page to another working.
$routeProvider as below:
angular.module('opalApp', ['opalApp.project','opalApp.services'])
/*, 'ui.bootstrap' */
.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when('/home', {templateUrl: 'parts/opalhome.html'});
$routeProvider.when('/projects', {templateUrl: 'parts/projects.html'});
$routeProvider.when('/projects/:projectSk', {templateUrl: 'parts/project.html', controller:'ProjectCtrl'});
})
It is the last $routeProvider to /projects/:projectSk I have the issue with:
I am presenting a list of projects, and providing a link to a detail page. List of projects as below:
<div ng-repeat="project in projects | filter:search | orderBy:orderProp track by $index" >
<p>Project:{{project.projectNm}}</p>
<ul>
<li>Disease Area: {{project.diseaseArea}}</li>
<li>Tier: {{project.approvedPriority}}</li>
<li>Status: {{project.planningStatus}}</li>
</ul>
</div>
The href to projects/{{project.projectSk}}" is working and is taking me to parts/project.html and returning the data for the project.
ProjectCtrl controller is below:
opalApp.controller('ProjectCtrl',['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
$http.get('resources/project/projects/' + $routeParams.projectSk).success(function(data) {
$scope.project = data;
});
}]);
My issue is, when I then do a manual browser refresh on the detail page
http://localhost:8080/misf-web/projects/75557
I get a load of errors in chrome as the path to the css and js files has been "amended" to have a /projects/ component in it. And these cannot be found (not surprisingly as /misf-web/projects doesn't exist its a url rewrite)
/misf-web/projects/lib/angular/angular.min.js
/misf-web/projects/lib/angular/angular-resource.min.js
/misf-web/projects/lib/bootstrap/bootstrap.min.js
/misf-web/projects/js/opalapp.js
/misf-web/projects/js/opalproject.js
/misf-web/projects/js/opalservices.js
In the main parent view these are all defined as below:
<link rel="stylesheet" href="css/bootstrap.min.css" media="screen" />
<link rel="stylesheet" href="css/bootstrap-theme.min.css" media="screen" />
<link rel="stylesheet" href="css/app.css" />
<script src="lib/jquery/jquery-2.0.3.min.js"></script>
<script src="lib/angular/angular.min.js"></script>
etc.
Note the lack of the added "projects" section in the URLs....
Any advice appreciated.
Regards
i
i have a lot of question about the angular ui-router module.
I'm tryin to understand it well before implement my applications with that one, but i have problems even with simple things.
HTML
<!doctype>
<html ng-app='myapp'>
<head>
<title>main</title>
<meta charset="utf-8">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<!--controller-->
<script src="app.js"></script>
<script src="controller.js"></script>
<!-- endbuild -->
</head>
<body>
hi
<div ui-view="view1"></div>
<div ui-view="view2"></div>
</body>
</html>
EDIT
var app=angular.module('myapp',['ui.router'
]);
app.config(function($stateProvider/*,$urlRouteProvider*/){
//$urlRouteProvider.otherwise("view1");
$stateProvider.
state('father',{
abstract:true,
template:'<div ui-view></div>',
controller:function($scope){
$scope.view='hi';
}
}).
state('son',{
parent:'father',
url:'/',
views:{'view1':{
templateUrl:'view1.html'
},
'view2':{
templateUrl:'view2.html'
}
}
})
})
and this is my js plunker http://plnkr.co/edit/hsEFKhpaGkIkzarQiuQQ?p=preview.
Now the questions:
1) As you can see in the index.html nothing appears, and my first intention is to see both the views in the main window
2)i have build an abstract state to pass a $scope.view to all the child state, but it seems it didn't work too
3)If what i want to do is done in the wrong way, what's the better approach to do it?
After spending more time than I should have playing around with it, I think I figured out what you were looking for.
I made a few changes and I will try to go over them all.
In the HTML, I added ui-router, moved your js script tags to just before </body>, that allowed me to get rid of all the console errors:
<!doctype>
<html ng-app='myapp'>
<head>
<title>main</title>
<meta charset="utf-8">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ui-view ></div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<script src="ui-router.js"></script>
<script src="app.js"></script>
</body>
</html>
Than in your app.js file I made a few changes:
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when('', '/');
$stateProvider
.state('father', {
abstract: true,
// I couldn't get this to work without a templateUrl for some reason,
// I'm sure with a little time you could figure this part out.
templateUrl: 'father.html',
controller: function($scope) {
$scope.view = 'Hello Dad';
console.log($scope.view);
}
})
.state('father.son', {
parent: 'father',
url: '/',
views: {
// Added the absolute target declaration `#father`, see link 1 below
'view1#father': {
templateUrl: 'view1.html',
controller: function($scope) {
console.log($scope.view);
}
},
'view2#father': {
templateUrl: 'view2.html',
controller: function($scope) {
console.log($scope.view);
}
}
}
})
});
Here is the father.html template:
<!-- Big file, I know -->
<div ui-view="view1"></div>
<div ui-view="view2"></div>
Link 1: View Names - Relative vs. Absolute Names
Link 2: Plunker