Nested Views and States Not showing - angularjs

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': {

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"
}
}
})

AngularJS $stateprovider

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"

ui-router named views and ng-controller

I have named views:
.state('home', {
url: '/',
views: {
'' : {
templateUrl: '/layouts/main.html',
controller: ['$rootScope', function($rootScope) {
$rootScope.css.background = "#ebeced";
}]
},
'nav#home': { templateUrl: '/templates/nav.html' },
'menu#home': { templateUrl: '/home/menu.html'},
'main#home': { templateUrl: '/templates/feed.html' },
'footer#home': { templateUrl: '/home/footer.html' }
}
})
and main.html looks like this (notice the ng-controller):
<div ng-controller="baseCtrl">
<div ui-view="nav"></div>
<div class="wrapper">
<div id="menu">
<div ui-view="menu"></div>
</div>
<div ui-view="main"></div>
<div id="footer">
<div ui-view="footer"></div>
</div>
</div>
</div>
My baseCtrl is not recognising ng-model values in text boxes in any of the ui-views.
<input type="text" ng-model="url" ng-blur="addUrl()" />
and the baseCtrl:
$scope.url = ""; //required or get error about not being defined
$scope.addUrl = function() {
console.log($scope.url); //nothing???
}
Am I making a stupid mistake anywhere?
UPDATE:
I think I've solved the problem - I need to define baseCtrl as the controller for each view too.
This block may be uncorrect:
'' : {
templateUrl: '/layouts/main.html',
//..etc
Are you sure that unnamed item should be a key in the state config object? You may try to put it differenlty:
.state('home', {
url: '/',
templateUrl: '/layouts/main.html',
controller: ['$rootScope', function($rootScope) {
$rootScope.css.background = "#ebeced";
}],
views: {
'nav#home': { templateUrl: '/templates/nav.html' },
'menu#home': { templateUrl: '/home/menu.html'},
'main#home': { templateUrl: '/templates/feed.html' },
'footer#home': { templateUrl: '/home/footer.html' }
}
})

Multi views with children

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.

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);
});

Resources