Child state doesn't load within parent - javascript

I am having trouble working out how to structure my routing code with UI router.
In my index file, I call in the menu template and 2 sidebar templates as follows:
index.html
<!-- head code above here -->
<body ng-app="ICP_App" ng-cloak>
<div layout-fill layout="row" ng-controller="AppController as AppCtrl">
<div ui-view="left-nav"></div>
<div ui-view="right-nav"></div>
<div ui-view="toolbar"></div>
<!-- this is where I am expecting/wanting my dashboard template to load (and others when at the correct url-->
<div class="page-content view" ui-view></div>
<!-- footer code under here -->
My routes:
$urlRouterProvider.otherwise('dashboard');
$stateProvider
.state('root', {
abstract: true,
templateUrl: '../partials/icp_index.html',
controller: 'AppController as AppCtrl',
url: '',
views: {
'left-nav': {
templateUrl: '../partials/left-nav.html'
},
'right-nav': {
templateUrl: '../partials/right-nav.html'
},
'toolbar': {
templateUrl: '../partials/toolbar.html'
}
}
})
.state('root.dashboard', {
url: '/dashboard',
templateUrl: '../partials/agency-dashboard.html',
controller: 'AppController as AppCtrl'
})
However, the menu and sidebars load, but the main content area is left blank. I wonder if it is to do with the '.otherwise'?
My index file should contain the menu and sidebars, then the content for that state to be loaded where I have indicated above - in this case the dashboard template. The '.otherwise' is there to show the dashboard (within the index file) when a url is incorrect or incomplete.
Thanks in advance.

You have to name that ui-view, and on your child state, you need to specify and/or override the desired view, so it would be something like:
<div class="page-content view" ui-view="main-content"></div>
and the state definition:
.state('root.dashboard', {
url: '/dashboard',
views: {
'main-content#root': {
templateUrl: '../partials/agency-dashboard.html',
controller: 'AppController as AppCtrl'
}
}
})
Also you should have two templates, one only defines the root ui-view (index.html), and the other one is your icp_index which contains the named views. This plunkr shows the structure:
plnkr.co/edit/zjngTr0JU6cUGBtMsfN0

Related

Nested View within Multiple views using ui router angularjs

I have multiple views on one page and within one view I have nested view.How should I configure this in app.js.Given below is my code which is not working.
This is my index.html file
<body ng-app="configuratorApp" >
<div ui-view="view1"></div>
<div ui-view="view2"></div>
</body>
This is my view1.html file
<div ui-view> </div>
<button type="button" ui-sref="view1.child1"></button>
<button type="button" ui-sref="view1.child2"></button>
This is my view1-child1.html file
<h1>Child1<h1>
This is my view1-child2.html file
<h1>Child2<h1>
This is my view2.html file
<h1>Hello World</h1>
This is my app.js file
.state('home',{
url: '/',
views: {
'': {
templateUrl: 'index.html'
},
'view1#home': {
templateUrl: 'view1.html'
},'view2#home': {
templateUrl: 'view2.html'
}
}
})
.state('view1.child1', {
url: '/child1',
templateUrl: 'view1-child1.html'
})
.state('view1.child2', {
url: '/child2',
templateUrl: 'view1-child2.html'
})
You confused the views with the states.
There is no view1.child1 state, reason being you do not have a view1 as a parent state (unless the code you posted above is incomplete). The name should be home.child instead.
.state('home.child1', { //this should be home.child1 instead of view1.child1
url: '/child1',
templateUrl: 'view1-child1.html'
})
.state('home.child2', {
url: '/child2',
templateUrl: 'view1-child2.html'
})
Also bear in mind that you will need a root template (or unnamed root template) in your index.html, else your homestate cannot be populated.
So in your index.html, you need to have this:
<body ng-app="configuratorApp">
<div ui-view></div> <!--this is the root template, to let Home state 'live' here-->
</body>
Here is the working plnkr
P.s. if the plnkr is not working just refresh it. sometimes it has problem fetching the htmls

Angular UI Router Abstract template

I have a working application with everything working with a structure like this:
<div class="container">
<div class="row">
<div class="col-md-2">
<!-- alot of repeated html used by all the states here -->
</div>
<div class="col-md-8">
<!-- the unique html specific to the state goes here -->
</div>
</div>
</div>
and router config like this
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: './partials/dashboard.html'
})
.state('applications', {
url: '/applications',
templateUrl: './partials/applications.html'
})
.state('server', {
url: '/server',
templateUrl: './partials/server.html'
})
The problem is that here is a lot of repetition of html code.
How do I make an interface that all states inherit from so that I concentrate on uniques html of a state.
You can use abstract state, f.e. called base:
.state('base', {
url: '',
templateUrl: 'path/to/layout.html', // here you should declare named ui-views, f.e. named content
abstract: true
})
.state('base.dashboard', {
url: '/dashboard',
views: {
content: {
templateUrl: "/path/to/dashboard/content.html"
}
}
})
// the rest of the states goes the same below.
...
Hope that helped somehow.
For more info please refer here.

Angular ui-router with multiple views not being displayed

I have the following state declared:
.state('select', {
url: '/select/:youtubeId',
views: {
'': {templateUrl: 'partials/select/select.html'},
video: {
templateUrl: 'partials/select/select.video.html',
controller: 'RecordVideoController'
},
setParts: {
templateUrl: 'partials/select/select.set-parts.html',
controller: 'RecordPartsController'
},
listParts: {
templateUrl: 'partials/select/select.list-parts.html',
controller: 'RecordPartsController'
}
}
})
All template files exist, this is for example, partials/select/select.html:
<div>
<div class="row">
<div ui-view="video" class="col-sm-9"></div>
<div class="col-md-3 text-center">
<div class="row">
<div ng-class="{'col-md-12': parts.length == 0, 'col-md-6': parts.length !== 0}" ui-view="setParts"></div>
<div ng-show="parts.length" ui-view="listParts" class="col-md-6"></div>
</div>
</div>
</div>
<div ui-view="ui-view"></div>
</div>
So, as it can be seen it only define the layout in order to set the proper state views.
Them problem is that none of the other views is being rendered, neither the corresponding controllers is being instantiated.
How is it supposed to work?
can you provide total code , then i can check your states declared correct or no i am also thinking that your not using nested states correctly
[enter link description here][1] check below link
Angular ui router multiple named views for all states
.state('select', {
url: '/select/:youtubeId',
views: {
'': {templateUrl: 'partials/select/select.html'},
//viewName#stateName
'video#select': {
templateUrl: 'partials/select/select.video.html',
controller: 'RecordVideoController'
},
'setParts#select': {
templateUrl: 'partials/select/select.set-parts.html',
controller: 'RecordPartsController'
},
'listParts#select': {
templateUrl: 'partials/select/select.list-parts.html',
controller: 'RecordPartsController'
}
}
})
try like this ..
I don't think you're nesting your views correctly. It's been a while since I worked with ui-router, but I think your nested states should look something like
video#select: {
templateUrl: 'partials/select/select.video.html',
controller: 'RecordVideoController'
},
Also, I'm not sure what you're trying to do with the <div ui-view="ui-view"></div> line - I think that can just be <div ui-view></div> if you're trying to render the default view there, or you need to specify which view you want as you did above.

how to load views in a base html view in angular?

I Need to load two html files in a base html file .In other words I have base html file in which I have header and contend view .I need to load different HTML file in header and in contend view ..
Here is Base HTML file
<div class="container">
<div class="row page-header">
<ui-view name="header"></ui-view>
</div>
<ui-view name="content"></ui-view>
<div class="row">
<div class="col-xs-12">
<hr>
<p class="text-center">Test Come</p>
</div>
</div>
</div>
In this view
<ui-view name="header"></ui-view>
in header I need to load header.html and <ui-view name="content"></ui-view> in thisI need to load content.html
http://plnkr.co/edit/nMhlb0R1q3BhWBHEjCks?p=preview
Thanks
You need to update your state according to child states:
var config = function($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('main', {
url: '/',
views: {
// the main template will be placed here (relatively named)
'': { templateUrl: 'base.html' },
// the child views will be defined here (absolutely named)
'content#main': { template: 'contend.html' },
// for column two, we'll define a separate controller
'header#main': {
templateUrl: 'header.html',
}
}
});
};
You can have just one ng-view.
You can change its content in several ways: ng-include, ng-switch or mapping different controllers and templates through the routeProvider.
UI-Router is a project that may help: https://github.com/angular-ui/ui-router One of it's features is Multiple Parallel Views
EDIT
Checkout this plnkr
There were some problem with your code
(1) inject $stateProvider instead of $routeProvider if you are uing ui-router
(2) use ui-view instead of ng-view
(3) you can have multiple view at same template level. If you tries to define ui-view inside ui-view and you create multiple ui-view in single state, it will not work.
(4) ui-view inside ui-view will create another state.
var app=angular.module("firstApp",['ui.router']);
var config = function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('base', {
url: "/",
views: {
"content": { templateUrl: "contend.html" },
"header": { templateUrl: "header.html" }
}
})
};
config.$inject = ['$stateProvider', '$urlRouterProvider'];
var loginCntrl=function($scope){
}
loginCntrl.$inject=['$scope']
app.config(config);
app.controller(loginCntrl);

Angular UI Router - Views in an Inherited State

edit: Based on the answer by #actor2019 I want to update my question to better explain the problem:
Using Angular UI-Router(v0.0.2), I've setup the app to properly navigate between main "pages"/state, while inheriting the base state.
Index.html:
<div ui-view></div>
base.html:
<!-- Header -->
<div>
<!-- Header markup -->
<!-- Search View -->
<div ui-view="search"></div>
</div>
<!-- Page Content view -->
<div ui-view></div>
The issue is here in the app.js file. When I add the views parameter to the base state, everything stops working(100% blank page). Without that parameter, the page renders correctly, but I have no search view.
app.js:
$urlRouterProvider.otherwise('/');
//
// Now set up the states
$stateProvider
.state('base', {
abstract: true,
templateUrl: 'views/base.html',
views: {
"search": {
templateUrl: "views/search.html"
}
}
})
.state('base.home', {
url: "/",
templateUrl: "views/home.html"
})
.state('base.page2', {
url: "/page2",
templateUrl: "views/page2.html"
});
How do I add views to this parent 'base' state?
UPDATE:
The problem with #actor2019's answer here is that the search view gets reinitialized when the state changes. I'd like the views off the base level to persist through state changes.
The first obvious mistake:
You can't specify controller and template on the state while your using views. They are mutually exclusive...
This is because when there is no "views" but a controller and template on the state, UI-Router automatically creates the "views" property and pulls those properties to an "empty" view...
.state('base', {
abstract: true,
templateUrl: 'views/base.html', //Can't do this
views: { // when this is there.
"search": {
templateUrl: "views/search.html"
}
}
})
Instead do:
.state('base', {
abstract: true,
views: {
"": {
templateUrl: 'views/base.html'
},
"search": {
templateUrl: "views/search.html"
}
}
})
Second problem:
How views targeting works with nested views etc. is not very logical, it may work well if you restrict your self to one view in one view all the way down, but ones you start working with multiple named views it all gets confusing... Add unnamed views on top and many people gets lost...
The way views work in UI-Router is the worst part of UI-Router...
Given you example I am not even entirely sure of the way to target the search view from your abstract parent state... Might be:
.state('base', {
abstract: true,
views: {
"": {
templateUrl: 'views/base.html'
},
"search#base": {
templateUrl: "views/search.html"
}
}
})
If it can even be made to work... Alternatively you can move the search view out of base.html, but I guess you added it in there for a reason.
The whole view concept is the biggest reason why I ended up writing https://github.com/dotJEM/angular-routing instead.
The Child state should be home.search instead of header.search. In your case, you may want to write some abstract state to hold the layout,
base.html
<div class="row-fluid">
<div class="header">
<div class="span3" ui-view="logo"></div>
<div class="span9" ui-view="menu"></div>
</div>
</div>
<div class="row-fluid">
<div class="content">
<div class="span2" ui-view="sidebar"></div>
<div class="span10" ui-view="entry"></div>
</div>
</div>
in app.js
$stateProvider
.state('base',{
abstract:true,
url:'/',
templateUrl: viewBase+'base.html'
})
.state('base.main',{
url:'',
views:{
"logo":{
templateUrl:viewBase+'main/logo.html'
},
"menu":{
templateUrl:viewBase+'main/menu.html'
},
"sidebar":{
templateUrl:viewBase+'main/sidebar.html'
},
"entry":{
templateUrl: viewBase+'main/entry.html'
}
}})
According to the ui-router documentation, when the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well. So, for example, when the "contacts.list" state is active, the "contacts" state is implicitly active as well, because it's the parent state to "contacts.list". Child states will load their templates into their parent's ui-view. I'd reccomend looking over the section of their documentation entitled Nested States & Views to gain a fuller understanding of how to do this.
In the code you have provided us here, the parent state of the search template is home, while
.state('header.search', {
templateUrl: "views/search.html",
controller: "SearchCtrl"
})
implies that the parent state of the search template should be header in order for the view to get loaded correctly. So, I believe the following changes to your app.js will fix your issue.
app.js
$stateProvider
.state('home', {
url: "/",
views: {
'': {
templateUrl: "views/mainContent.html",
controller: "MainCtrl"
},
'header': {
templateUrl: "views/header.html"
},
'footer': {
templateUrl: "views/footer.html"
},
}
})
.state('home.search', {
views: {
'search': {
templateUrl: "views/search.html",
controller: "SearchCtrl"
}
})
.state('anotherPage', {
url: "/anotherPage",
templateUrl: "views/anotherPage.html"
});
This works for me.
$stateProvider
.state('base', {
abstract: true,
url:'/',
templateUrl: 'views/base.html'
})
.state('base.home', {
url: "",
views: {
"search#base": {
templateUrl: "views/searchOfHome.html"
}
//content#base, contentOfHome.html
}
})
.state('base.page2', {
url: "page2",
views: {
"search#base": {
templateUrl: "views/searchOfPage2.html"
}
//content#base, contentOfPage2.html
});
If 'base' is the root state, you don't need the '#base'

Categories