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);
});
Related
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"
I have a layout with header, footer, sidebar and content that should be used for some pages. All pages should be includes inside the content section.
<div class="wrapper">
<header class="main-header" ui-view="header"></header>
<aside class="main-sidebar" ui-view="left"></aside>
<div class="content-wrapper" ui-view></div><!-- all pages should be included here -->
<footer class="main-footer" ui-view="footer"></footer>
<aside class="control-sidebar control-sidebar-dark" ui-view="right"></aside>
<div class="control-sidebar-bg"></div>
</div>
My routes:
.state('main', {
views: {
'left': {
templateUrl: 'partials/design/left.html'
},
'header': {
templateUrl: 'partials/design/header.html'
},
'right': {
templateUrl: 'partials/design/right.html'
},
'footer': {
templateUrl: 'partials/design/footer.html'
}
},
url: '/'
})
.state('info', {
url: '/info',
templateUrl: "partials/info.html",
})
.state('foobar', {
url: '/foobar',
templateUrl: "partials/foobar.html",
})
So info and foobar should be childrens of main, but I don't know how to do this.
Instead of
.state('info', {
url: '/info',
templateUrl: "partials/info.html",
})
.state('foobar', {
url: '/foobar',
templateUrl: "partials/foobar.html",
})
Do this:
.state('main.info', {
url: '/info',
templateUrl: "partials/info.html",
})
.state('main.foobar', {
url: '/foobar',
templateUrl: "partials/foobar.html",
})
I found out that it is also possible with ng-include
<div class="wrapper">
<header class="main-header" ng-include src="'partials/design/header.html'"></header>
<aside class="main-sidebar" ng-include src="'partials/design/left.html'"></aside>
<div class="content-wrapper"><ui-view></ui-view></div><!-- all pages should be included here -->
<footer class="main-footer"ng-include src="'partials/design/footer.html'"></footer>
<aside class="control-sidebar control-sidebar-dark" ng-include src="'partials/design/right.html'"></aside>
<div class="control-sidebar-bg"></div>
</div>
So everyone who has this template as parent will be shown in the <ui-view></ui-view>section.
In my app I have the root state named "app":
.state('app', {
abstract: true,
views: {
'app': {
templateUrl: 'prebuilt/views/pages/index.html',
controller: 'MainController'
}
}
})
and its child "app.pages"
.state('app.pages', {
abstract: true,
views: {
'custom#app': {
templateUrl: 'prebuilt/views/templates/custom-styles.html'
},
'header#app': {
templateUrl: 'prebuilt/views/layout/header.html'
},
'topBar#app': {
templateUrl: 'prebuilt/views/layout/topbar.html'
},
'sideBar#app': {
templateUrl: 'prebuilt/views/layout/sidebar.html'
},
'infoBar#app': {
templateUrl: 'prebuilt/views/layout/infobar.html'
},
'contentSide#app': {
templateUrl: 'prebuilt/views/layout/contentside.html'
}
}
})
And grand child "app.pages.dashboard"
.state('app.pages.dashboard', {
url: '/',
views: {
'content#app.pages': {
templateUrl: 'prebuilt/views/index.html',
controller: 'DashboardController'
}
},
resolve: {
loadCalendar: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load([
'prebuilt/bower_components/fullcalendar/fullcalendar.js',
]);
}]
}
})
Now app loads an html view, inside that view are nested views which are/should be loaded when i navigate to "app.pages".
Now up to this point everything works just fine, however now I want to load a page in the content body of "app.pages", I've tried several times but the view never gets loaded:
This is a simplified version of my app.php:
<html>
<head></head>
<body>
<div ui-view="app"></div>
</body>
</html>
This is a simplified version of my index.html:
<div ui-view="header"></div>
<nav ui-view="topBar"></nav>
<div id="wrapper">
<div>
<di ui-view="sideBar">
</div>
<div>
<div>
<div>
<div class="col-md-9" ui-view="content">
</div>
<div class="col-md-3" ui-view="contentSide">
</div>
</div> <!--wrap -->
</div>
<footer>
<div class="clearfix">
<ul class="list-unstyled list-inline pull-left">
<li>© 2015</li>
</ul>
<button><i class="fa fa-angle-up"></i></button>
</div>
</footer>
</div>
</div>
</div>
<div ui-view="infoBar"></div>
One issue is incorrect absolute naming here:
// NOT correct
.state('app.pages.dashboard', {
url: '/',
views: {
// here is incorrect absolute name
'content#app.pages': {
templateUrl: 'prebuilt/views/index.html',
controller: 'DashboardController'
}
},
...
Because this is part of index.html, which is part of state 'app'
...
<div class="col-md-9" ui-view="content">
...
So the proper naming is just '...#app'
.state('app.pages.dashboard', {
url: '/',
views: {
// CORRECT
'content#app': {
I need two views which will be showed independently of each other. But when I click on the one the other being removed. I need not a child state but like a siblings. It is even possible?
Please, help. This is my Plnkr
<body ng-app="SiblingViews">
<h1>Hello Plunker!</h1>
<div>
<a ui-sref="view1">View_1</a>
<a ui-sref="view2">View_2</a>
</div>
<div ui-view="first"></div>
<div ui-view="second"></div>
</body>
$stateProvider
.state('view1', {
url: '/view-1',
views: {
'first': {
templateUrl: 'first.html'
}
}
})
.state('view2', {
url: '/view-2',
views: {
'second': {
templateUrl: 'second.html'
}
}
});
I am having a problem in my view. The view is loaded twice and I have no idea what's going on.
What I have done in my index file is this:
<body class="ng-cloak">
<!--Menus-->
<div class="container-fluid">
<div data-ng-controller="HomeCtrl" class="row">
<!--Here is the ui view directive-->
<div class="col col-md-12" data-ui-view ></div>
</div>
</div>
<!--script files here-->
</body>
On the routes file I have these. The problem only occurs when i visit the contact.inner page
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/home.html'
})
.state('contact', {
url: '/contact',
templateUrl: 'partials/contact.html'
})
.state('contact.inner', {
url: '/inner',
templateUrl: 'partials/inner.html'
});