I have a question about multiple views. It's difficult to explain but I'll try:
Navigating to state 'About' and setting template url for ui-view 'columnOne' and ui-view 'columnTwo' was done succesfully
.state('about', {
url: '/about',
views: {
// the main template will be placed here (relatively named)
'': { templateUrl: 'partial-about.html' },
// the child views will be defined here (absolutely named)
'columnOne#about': { template: 'Look I am a column!' },
// for column two, we'll define a separate controller
'columnTwo#about': {
templateUrl: 'table-data.html',
controller: 'scotchController'
}
}
});
Now I would like to set the templateUrl of view 'columTwo' from view 'columnOne'.
How is this done? Is it possible?
The example your taking from there website is parallel view example not nested view nested view can be made by making a page and than making other states with . like registration is a page and multistep form than the page containing registration uiview will we state registration and the parts with be like registration.contact,registration.acadamics, registration.extraactivities. And really man there documentation is quiet confusing
Related
In my Angular app, I have the following sample route definition which uses nested views:
.state('mapping.project', {
authenticate: true,
url: '/:projectId/:projectName',
controller: 'ProjectCtrl as proj',
views: {
'': {
templateUrl: 'app/components/mapping/partials/project.html',
controller: 'ProjectCtrl as proj'
},
'details#project': {
templateUrl: 'app/components/mapping/partials/details.html'
},
'activityTypes#project': {
templateUrl: 'app/components/mapping/partials/activity-types.html'
},
'boundaryPartners#project': {
templateUrl: 'app/components/mapping/partials/boundary-partners.html'
},
'progressMarkers#project': {
templateUrl: 'app/components/mapping/partials/progress-markers.html'
},
'users#project': {
templateUrl: 'app/components/mapping/partials/users/users.html',
controller: 'projectUserCtrl as vm'
}
}
})
Each of these views is loaded within a tab, using Angular Material md-tabs: https://material.angularjs.org/latest/api/directive/mdTabs
The problem is, when I access the route mapping.project, the projectUserCtrl that you can see on my users#project view gets immediately called. I assume the same would be true for each individual controller that I have attached to my nested views.
I'd want to call these nested controllers only when the tab is active and that particular template loaded (in this case: users#project).
How do I do this?
You don't need all these child views, you only need 1, a container for the visible tab. Make separate states for each of the tabs, then route the child view accordingly when your "tabs" are clicked.
I'm not sure on the material design specifics, but in essence your tabs become just links ui-sref links.
I have app with many main states, one of them is user profile:
$stateProvider.state('profile', {
url: '/profile/',
templateUrl: 'profile/profile.html',
controller: 'Profile',
});
But this is just an container for nested pages with different profile settings. It's template only contains main menu and ui-view for nested states. Controller is only for that menu handling.
One of nested views should be default url and have same URL as parent, so there shouldn't be any suffixes added into url, but I can't achieve that.
Here's what I tried:
$stateProvider.state('profile.details', {
url: '',
templateUrl: 'profile/details.html',
controller: 'ProfileDetails',
});
this is not working at all, at url /profile/ only menu appears and an empty ui-view element. Second approach:
$stateProvider.state('profile.details', {
url: '/',
templateUrl: 'profile/details.html',
controller: 'ProfileDetails',
});
This matches on url /profile// (with 2 slashes at end). At url /profile/ there is still menu and empty ui-view element.
How can I achieve that result? Is this even possible using angular-ui-router?
Make your parent state abstract. This will prevent from going into that state, and force to go to child states only. Abstract states are perfect as templates for child ones. Also get rid of url:
$stateProvider.state('profile', {
abstract: true,
templateUrl: 'profile/profile.html',
controller: 'Profile',
});
Now for your child state define absolute URL
$stateProvider.state('profile.details', {
url: '^profile',
templateUrl: 'profile/details.html',
controller: 'ProfileDetails',
});
That should work.
I have tried several examples on using the ui-router and the state manager. My nested views and routes are not working as I hoped. Here is an example of how I am configuring the states:
$stateProvider
.state("main", {
abstract: true,
url: "/main",
views: {
"layout": {
templateUrl: "main.index.html"
},
"mainNavigation#main": {
templateUrl: "main-navigation-partial.html"
}
},
onEnter: function() {
console.log("enter main");
}
})
.state("main.dashboard", {
url: "/dashboard",
views: {
"container#main": {
templateUrl:"main-dashboard.html"
}
}
});
As you can see, I have an abstract state named main. All main views will use the mainNavigation view. There is also a container view area where the content for each section will reside. There is an index.html that will be used by all states. So, I may, down the road have an abstract state name client with accompanying states and views.
I can see the individual html files being loaded, but the views are not being populated in the correct named view areas. I have created a plunk that demonstrates how I want to manage my templates and views.
Your main state is loading main.index.html into a ui-view named layout. In your plunker, your root ui-view is unnamed. So to fix this, add a name to that ui-view.
http://plnkr.co/edit/xKDcuk99OACQR73LR0hf?p=preview
<div ui-view='layout'>
Or, you could leave the ui-view unnamed and change the view to reflect that.
"": {
templateUrl: "main.index.html"
}
For more on view naming, see the ui-router wiki.
I have the following layout:
Sidebar and Headerbar will always be present though their content is context-specific.
I think there are two options here: nested states (sidenav > Headerbar > Content) or with views (if I understand that correctly). I'm still struggling to get my head wrapped around ui-router regardless of how many videos and articles I've read.
Clicking on Sidenav would load a state (or view) into Content and Headerbar would adjust its content based on whatever is loaded into Content.
My sense is that nested states seem like the simplest direct approach, particularly when thinking about inheritance.
Looking at it from another point of view, these seem like they could be siblings (although inheritance issues probably make me wrong). My inkling is that views would allow me more flexibility in the future with sub-items and such.
And of course ng-include and directives could play into this.
Being new to ui-router could someone slap me in the right direction? Where I'm stuck is loading the home view. I want my users to see their dashboard in the Content section once they log in. And then, how do I load new elements into Content as the user navigates from the Sidebar?
One way how to design scenario with 1) side bar, 2) action section and 3) main area could be like in this working example
Firstly the root state. Here is root state named 'index'. It is abstract and could do some resolve for us. It does not effect child state naming and does not extend the url (because is undefined)
$stateProvider
.state('index', {
abstract: true,
//url: '/',
views: {
'#' : {
templateUrl: 'layout.html',
controller: 'IndexCtrl'
},
'top#index' : { templateUrl: 'tpl.top.html',},
'left#index' : { templateUrl: 'tpl.left.html',},
'main#index' : { templateUrl: 'tpl.main.html',},
},
})
The first real state is list, and it inherits from parent but with an attribute parent: 'index', so the parent name is not effecting the state name.
Advantage is, that it could inherit lot of resolved stuff. Also, the root state could be loaded once, for all other parent states
.state('list', {
parent: 'index',
url: '/list',
templateUrl: 'list.html',
controller: 'ListCtrl'
})
This is the real power of UI-Router, because now we can see that child is injecting stuff into two places - 1) action section and 2) main area
.state('list.detail', {
url: '/:id',
views: {
'detail#index' : {
templateUrl: 'detail.html',
controller: 'DetailCtrl'
},
'actions#index' : {
templateUrl: 'actions.html',
controller: 'ActionCtrl'
},
},
})
This way, we can use named views and multi views in real world scenario. Please, never forget how the scope definition goes:
Scope Inheritance by View Hierarchy Only
Keep in mind that scope properties only inherit down the state chain if the views of your states are nested. Inheritance of scope properties has nothing to do with the nesting of your states and everything to do with the nesting of your views (templates).
It is entirely possible that you have nested states whose templates populate ui-views at various non-nested locations within your site. In this scenario you cannot expect to access the scope variables of parent state views within the views of children states.
Check that all in action here
I just would like to share my experience. There is
similar Q & A: Angular UI Router - Nested States with multiple layouts
and a link to working plunker
The snippet of the state def:
$stateProvider
.state('index', {
url: '/',
views: {
'#' : {
templateUrl: 'layout.html',
controller: 'IndexCtrl'
},
'top#index' : { templateUrl: 'tpl.top.html',},
'left#index' : { templateUrl: 'tpl.left.html',},
'main#index' : { templateUrl: 'tpl.main.html',},
},
})
.state('index.list', {
url: '/list',
templateUrl: 'list.html',
controller: 'ListCtrl'
})
.state('index.list.detail', {
url: '/:id',
views: {
'detail#index' : {
templateUrl: 'detail.html',
controller: 'DetailCtrl'
},
}
In a nutshell, I do use the nesting approach.
It is similar to the "core example" available here http://angular-ui.github.io/ui-router/sample/#/. It is hierarchical (entity list / detail)
And what's more, I use the hidden supper root state:
check the details here Updating resolved objects in ui.router parent states
the examle link
which is handling security related stuff - once, and shared among all child states:
$stateProvider
.state('root', {
abstract: true,
template: '<div ui-view></div>',
resolve: {objectX : function() { return {x : 'x', y : 'y'};}},
controller: 'rootController',
})
.state('home', {
parent: "root",
url: '/home',
templateUrl: 'tpl.example.html',
})
.state('search', {
parent: "root",
url: '/search',
templateUrl: 'tpl.example.html',
})
Hope it does enlighten this a bit, because the power of UI-Router I see in multiviews, view nesting, scope inheritance and the logical state machine behind
I would like to make a bootstrap tabset with each tab having it's own controller. Can anyone point me in which direction I should go.
Currently I have made several difference controllers, which I would like to be used in a tabset instead of having them displayed as a different route.
I know I could fake it by having the tabset in the difference controller templates displaying the given controllers tab as active, but I would like to be able to have a main TabController with several child controllers (for each tab)
If you are using angular ui router you can use nested states to do this.
Create an abstract state with a view that contains the tabs and a nested ui-view
Create a child state for each of your tabs, each inheriting from the abstract state
Each child state can set the content of the nested ui-view, and define a controller
$stateProvider.state( 'tabs', {
abstract: true,
url: 'tabs',
views: {
"tabs": {
controller: 'TabsCtrl',
templateUrl: 'tabs.html'
}
}
})
.state('tabs.tab1', {
url: '', //make this the default tab
views: {
"tabContent": {
controller: 'Tab1Ctrl',
templateUrl: 'tab1.html'
}
}
})
.state('tabs.tab2', {
url: '/tab2',
views: {
"tabContent": {
controller: 'Tab2Ctrl',
templateUrl: 'tab2.html'
}
}
});
Why don't you put a directive on each tab that has it's own controller? If you are using 1.x. Separate your code out by directive not tabs