AngularJS $stateprovider - angularjs

I am new to angularjs, I am not able to understand the concept of $stateprovider
I want to create a header that has menu and logo and the body content should change when clicked on menu items accordingly, code is given below, please check and answer my query
HTML
<div ui-view = "header"></div>
<div ui-view = "content"></div>
JS
var App=angular.module('test', ["ui.router", "App.controllers", "ui.bootstrap"]);
App.config(function ($stateProvider){
$stateProvider
.state('test', {
url: '',
views: {
'header': { templateUrl: '/templates/header.html'}
}
});
})
Thank You

Since you have taken two views, one for header and other for content,
<div ui-view = "header"></div>
<div ui-view = "content"></div>
The route also should have two different named routes.
views: {
'header': { templateUrl: '/templates/header.html'},
'content': { templateUrl: '/templates/content.html'}
}
From this,
<div ui-view = "header"></div> opens header.html and <div ui-view = "content"></div> opens content.html
Here is the code,
var App=angular.module('test', ["ui.router", "App.controllers", "ui.bootstrap"]);
App.config(function ($stateProvider){
$stateProvider
.state('test', {
url: '',
views: {
'header': { templateUrl: '/templates/header.html'},
'content': { templateUrl: '/templates/content.html'}
}
});
})
In the HTML,
<ul class="nav nav-pills main-menu right">
<li role="presentation"><a ui-sref="test" class="active">Home</a></li>
<li role="presentation">Bus Chart</li>
<li role="presentation">My Bookings</li>
<li role="presentation">Reviews</li>
<li role="presentation">Contact</li>
</ul>
The first li click goes to our test state as given in routes.
Here is the documentation for the same

In config File
// State definitions
$stateProvider
.state('test', {
abstract: true,
views: {
'main#': {
templateUrl: 'app/../../full-view.html'
},
'header#test': {
templateUrl: '/templates/header.html' // correct path to the template
// controller: 'HeaderController as vm' if needed
},
'footer#test': {
templateUrl: '/templates/footer.html' // correct path to the template
// controller: 'FooterController as vm' if needed
}
}
});
HTML
in content-only.html
<div>
<div ui-view = "content"></div>
</div>
in full-view.html
<div class="container">
<div ui-view="header"></div>
<div>
<div ui-view="content"></div>
</div>
<div ui-view="footer"></div>
</div>
in index.html
<body>
<div ui-view="main"></div>
</body>
in other modules(example)
views: {
'content#test': {
templateUrl: 'app/main/policies/policies.html'
// controller: 'PoliciesController as vm' if needed
}
}
so that whatever you append to content#test will comes under ui-view="content"
for routing avoid using href="", use ui-sref="" since you are using ui-router
example ui-sref="app.home" or ui-sref="app.about" rather than usinghref="#/home" or href="#/about"

Related

ui-sref not working state angularjs

I'm working on something and I want to redirect the content to a page in angularjs, but I face the following error:
angular.js:12477 Error: Could not resolve 'dashboard.home' from state 'dashboard'
My code:
.state(
'dashboard.home',
{
url: '/home',
views: {
"content#main": {
templateUrl: '/home'
// controller: 'HomeController',
}
}
}
)
.state(
'dashboard',
{
url: '',
parent: "main",
views: {
"sidebar#main": {
templateUrl: "/sidebar/view"
}
}
})
sidebar.html.twig
<li>
<a ui-sref="dashboard.home">Home <span class="sr-only">(current)</span></a>
</li>
The state 'dashboard.home' exists, why the error appears?
I think you're probably trynig to use views to split header/footer/siderbar from the content which is the only thing to change according states.
I don't have the answer of what exactly is your problem but I may have an answer to a more broader question that you might are trying to solve :
How to mix views for header/content/footer and nested stated for content navigation ?
Solution : use views only for header/content/footer, use '#' to insert direct child by using the default view (no name) and use grand child as you would do normally without views
// root state
.state('home', {
url:'/home',
views:{
'header':{
templateUrl: 'template/header.html',
controller:'HeaderCtrl'
},'sidepanel':{
templateUrl: 'template/sidepanel.html',
controller:'SidePanelCtrl',
},'footer':{
templateUrl: 'template/footer.html'
}
},
'abstract':false
})
//direct child
.state('home.main', {
url:'/main',
// need that for every direct child of home
views:{
'#':{templateUrl: 'template/main.html',
controller: 'MainCtrl'
}
}
})
//grandchild
.state('home.main.child1', {
url:'/child1',
templateUrl: 'template/child1.html',
controller: 'Child1Ctrl'
// NO view anymore for grand child!!
}
})
And the Relevant HTML
<section id="header">
<!--- not container -->
<div data-ui-view="header"></div>
</section>
<section id="content">
<div class="row clearfix">
<div id="mySidebar>
<div data-ui-view="sidepanel"></div>
</div>
<div id="myContent">
<div data-ui-view></div>
</div>
</div>
</section>
<section id="footer">
<div data-ui-view="footer"></div>
</section>
The templateUrl expects the relative path of the html template that you want to render.
.state(
'dashboard.home',
{
url: '/home',
views: {
"content#main": {
templateUrl: 'home.html'
}
}
}).state(
'dashboard',
{
url: '',
parent: "main",
views: {
"sidebar#main": {
templateUrl: "sidebar/view.html"
}
}
})

2 ui-view in the same page angularjs

I need to have 3 elements in a same view and I do not know how to do it, I have my ui-view = 'main' or I can display my menu but I do not know how to display the template Of the selected menu in the same view
this is my routing
routeApp.config(function($stateProvider, $urlRouterProvider,$locationProvider){
$stateProvider
.state("connexion", {
url: "/connexion",
templateUrl: 'Template/connexion.html',
controller: 'PostController'
})
.state("accueil", {
url: "/",
templateUrl: 'Template/connexion.html',
controller: 'PostController'
})
.state('agenda', {
url: "/agenda",
views: {
// for column two, we'll define a separate controller
'': {
templateUrl: 'Template/agenda.html',
controller: 'customersCtrl',
resolve:{
"check":function($cookies,$location){ //function to be resolved, accessFac and $location Injected
// console.log($cookies.get('user'));
if ($cookies.get('user')){ //check if the user has permission -- This happens before the page loads
// $cookies.remove('user');
}else{
$location.path('/'); //redirect user to home if it does not have permission.
alert("Vous devez vous connecter pour acceder a cette page");
}
}
}
},
'main':{
url: "/menu",
templateUrl: 'Template/menuAddAgenda.html'
/* //i want to put here
("bar", {
url: "/bar",
templateUrl: 'Template/bar.html'
})
("foo", {
url: "/bar",
templateUrl: 'Template/foo.html'
})
*/
}
}
})
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(true);
})
this is my modal code
<div class="modal-body" id="modal-body">
<div class="row">
<div class="span12 ui-view-container">
<div class="well" ui-view="main"></div>
</div>
</div>
<div ng-view></div>
and this my code menu
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Quick Start</a>
<ul class="nav">
<li><a ui-sref="foo">Route 1</a></li>
<li><a ui-sref="bar">Route 2</a></li>
</ul>
</div>
My menu displays correctly but I do not know how to set the route with my ui-sref To be displayed in the same view
if some one can help me
thans in advance

UI-Router parent view not working in angular

I'm creating an application and in the dashboard I have the header and the sidebar that will be in every single page of the dashboard, and for that reason I created partial files for them.
The problem is that if I access /dashboard/users I get the same thing that is in the /dashboard, I was wondering how to keep the header and sidebar but change the main content to the /views/dashboard/users.html file?
I created the states like this:
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'views/main.html',
controller: 'MainCtrl',
controllerAs: 'main'
})
.state('dashboard', {
url: '/dashboard',
views: {
'': {
templateUrl: 'views/dashboard.html'
},
'header#dashboard': {
templateUrl: 'views/dashboard/partials/header.html'
},
'sidebar#dashboard': {
templateUrl: 'views/dashboard/partials/sidebar.html'
}
},
controller: 'DashboardCtrl',
controllerAs: 'dashboard'
})
.state('dashboard.users', {
url: '/users',
views: {
'': {
templateUrl: 'views/dashboard/users.html'
}
},
controller: 'DashboardUsersCtrl',
controllerAs: 'dashboard/users'
});
});
/main.html
<p>main</p>
/index.html
<body ng-app="freelancerApp">
<div ui-view></div>
</body>
/views/dashboard.html
<div ui-view="header"></div>
<p>dashboard</p>
<div ui-view="sidebar"></div>
/views/dashboard/users.html
<div ui-view="header"></div>
<p>users</p>
<div ui-view="sidebar"></div>
/views/dashboard/partials/header.html
</p>header</p>
/views/dashboard/partials/sidebar.html
<p>sidebar</p>
I would say, that your parent template, is just missing place for a child (unnamed view target)
//views/dashboard.html
<div ui-view="header"></div>
<p>dashboard</p>
<div ui-view="sidebar"></div>
should be
//views/dashboard.html
<div ui-view="header"></div>
<div ui-view="">
// we can keep it or remove the content
<p>dashboard</p> // just visible in parent
</div>
<div ui-view="sidebar"></div>
Now, we have a target <div ui-view=""></div> for an unnamed child view, defined as views :{ '': {...}} in a .state('dashboard.users'...
Add abstract:true in this snippet
.state('dashboard', {
url: '/dashboard',
abstract: true,
views: {
'': {
templateUrl: 'views/dashboard.html'
},
'header#dashboard': {
templateUrl: 'views/dashboard/partials/header.html'
},
'sidebar#dashboard': {
templateUrl: 'views/dashboard/partials/sidebar.html'
}
},
controller: 'DashboardCtrl',
controllerAs: 'dashboard'
})

Use common templates for different states

I want to be able to use two common components through out my app in all the states basically the header and the sidebar. I have read through the docs but i must have missed something. How can i reuse the header and sidebar in the states
$stateProvider
.state('home', {
url: '/leads:id',
views: {
'details': {
templateUrl: '../views/details.html',
controllerProvider: function($stateParams) {
if($stateParams.id) {
return 'CompanyDetails as companydetails';
}else {
return 'NewCompanyDetailsController as companydetails';
}
}
},
'sidebar': {
templateUrl: '../views/sidebar.html'
},
'header': {
templateUrl: '../views/header.html',
controller: 'HeaderCtrl as header'
},
'vehicledetails': {
templateUrl: '../views/vehicledetails.html',
controller: 'VehicleDetailsController as vehicledetails'
},
'comments': {
templateUrl: '../views/comments.html',
controller: 'CommentsController as comments'
},
'saveupdate': {
templateUrl: '../views/saveupdate.html',
controller: 'SaveUpdateDetailsController as saveupdate'
}
}
});
I want to create another state called 'data' for example which reuses the header and sidebar. How can I acheive this without requiring to write down all the the components again ?
I did a bit of reading and now, I have an updated state provider that displays the common header and sidebar on all routes but the data inside the actual container is not being displayed at all. Here is my updated code
$stateProvider
.state('home', {
abstract: true,
views: {
'header': {
templateUrl: '../views/header.html',
controller: 'HeaderCtrl as header'
},
'sidebar': {
templateUrl: '../views/sidebar.html'
}
},
resolve: {
somedata: function(){return {}}
}
})
.state('home.login', {
url: '/',
views: {
'login#home': {
templateUrl: '../views/login.html'
}
}
})
.state('home.leads', {
url: '/leads:id',
views: {
'details#home': {
templateUrl: '../views/details.html',
controllerProvider: function($stateParams) {
if($stateParams.id) {
return 'CompanyDetails as companydetails';
}else {
return 'NewCompanyDetailsController as companydetails';
}
}
},
'vehicledetails#home': {
templateUrl: '../views/vehicledetails.html',
controller: 'VehicleDetailsController as vehicledetails'
},
'comments#home': {
templateUrl: '../views/comments.html',
controller: 'CommentsController as comments'
},
'saveupdate#home': {
templateUrl: '../views/saveupdate.html',
controller: 'SaveUpdateDetailsController as saveupdate'
}
}
});
and my index.html
<body ng-app="MyApp">
<div id="page-wrapper" ng-class="{'open': toggle}" ng-cloak class="open" ng-controller="SlideCtrl">
<div id="sidebar-wrapper" ui-view="sidebar">
</div>
<div id="content-wrapper">
<div class="page-content">
<!-- Header Bar -->
<div class="row header" ui-view="header">
</div>
<!-- Header Bar -->
<div ui-view="login"></div>
<div ui-view="details" class="panel panel-default col-xs-11" ></div>
<div ui-view="vehicledetails" class="panel panel-default col-xs-11" ></div>
<div ui-view="comments" class="panel panel-default col-xs-11" ></div>
<div ui-view="saveupdate"></div>
</div>
</div>
</div>
<script src="js/main.js"></script>
</body>
I actually managed to get this working now using this link https://stackoverflow.com/a/28826126/1679310
I will explain my answer since I couldnt understand how it worked before I did it on my own. You need this to be present for the child states to plug into it.
https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#scope-inheritance-by-view-hierarchy-only
Basically you create a main ng-view inside the index.html that serves as the container to your others partials then you basically contain all the child ui-views inside another layout that will serve as the parent to all the states.
So in essence your structure is something like this
<body ng-app="MyApp">
<div id="page-wrapper" ng-class="{'open': toggle}" ng-cloak class="open" ng-controller="SlideCtrl">
<div ng-view>
</div>
</div>
<script src="js/main.js"></script>
and another file that has the layouts
<div id="sidebar-wrapper" ui-view="sidebar">
</div>
<div id="content-wrapper">
<div class="page-content">
<!-- Header Bar -->
<div class="row header" ui-view="header">
</div>
<!-- Header Bar -->
<div ui-view="login"></div>
<div ui-view="details" class="panel panel-default col-xs-11" ></div>
<div ui-view="vehicledetails" class="panel panel-default col-xs-11" ></div>
<div ui-view="comments" class="panel panel-default col-xs-11" ></div>
<div ui-view="saveupdate"></div>
</div>
</div>
Then you basically follow the pattern here
$stateProvider
.state('home', {
abstract: true,
views: {
'#': {
templateUrl: '../views/layouts.html'
},
'header#home': {
templateUrl: '../views/header.html',
controller: 'HeaderCtrl as header'
},
'sidebar#home': {
templateUrl: '../views/sidebar.html'
}
}
})
.state('home.login', {
url: '/',
views: {
'login#home': {
templateUrl: '../views/login.html'
}
}
})
For all your states. This worked for me and I am pretty sure that is the right way to do so.
There's a better way:
HTML part
Index file (index.html):
<html ng-app="app">
<head></head>
<body ui-view></body>
</html>
Base file (layout.html)
<header>
Here's the header part
</header>
<aside>
Here's the sidebar part
</aside>
<main ui-view>
And here is where the app will be ran when you go to a state like "app.home"
</main>
States:
var states = {
'app': {
templateUrl: 'app/layout.html',
controller: 'LayoutController as layout'
},
'app.home': {
templateUrl: 'app/home.html',
controller: 'HomeController as home'
}
};
angular.forEach(states, function(config, name) {
$stateProvider.state(name, config);
});

How can I create a link in an angular app that loads inside a tab?

I have a link in an angular app that looks like this:
<tab ng-controller="childCtrl" heading="Children">
edit
</tab>
How can I load the link inside the tab instead of refreshing the entire view?
I like other approach with one point of handling all routes. ui.router with nested views allows to do it.
Template
<div ><a ui-sref="home.tab1" >Tab1</a></div>
<div><a ui-sref="home.tab2" >Tab2</a></div>
<br>
<div ui-view="tabs"></div>
app
var app = angular.module('plunker', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'main.html',
controller: 'MainCtrl',
virtual: true
})
.state('home.tab1', {
url: '/tab1',
views: {
tabs: {
templateUrl: '1.html'
}
}
})
.state('home.tab2', {
url: '/tab2',
views: {
tabs: {
templateUrl: '2.html'
}
}
});
$urlRouterProvider
.otherwise('/home/tab1');
})
And demo http://plnkr.co/edit/r1jPgkMnPAMlI34gZrMA?refresh&p=preview
You could define the path to the selected tab's content when the link is clicked, and use ng-include to display it.
<div ng-repeat="parent in parents">
<div ng-repeat="child in parent.children">
<a href="" ng-click="selectPath(parent, child);">
Parent {{parent.Id}}, Child {{child.Id}}
</a>
</div>
</div>
<div ng-include="selected.path"></div>
Here is a demo: http://plnkr.co/edit/7SPnluxUfcNNQDyeC6yt?p=preview

Resources