angular ui router state - multiple states with same template and controller - angularjs

I have states defined as below in my angularjs app using angular ui router state provider. And, I would like to define multiple states with the same configuration ie. with the same template and controller.
$stateProvider
.state('parent', {
templateUrl: 'parent.html',
abstract: true,
parent: 'apm'
})
.state('parent.list', {
abstract: true,
url: '/list',
templateUrl: 'list.html',
controller: 'ListCtrl'
})
.state('parent.list.closed', {
url: '/q',
templateUrl: 'closed.html'
})
.state('parent.list.details', { // would like to have same template, controller on different state parent.details without list
url: '/:id/:name',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
})
.state('parent.list.details.data', { // would like to have same template, controller on different state parent.details.data without list
url: '/details',
views : {
'view1' : {
templateUrl : 'view1.html'
},
'view2' : {
templateUrl : 'view2.html',
controller : 'View2Ctrl'
},
'view3' : {
templateUrl : 'view3.html'
},
'view4' : {
templateUrl : 'view4.html'
}
}
})
Is it possible to do something like
.state(['parent.list.details', 'parent.details'], {
url: '/:id/:name',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
})
Any help or suggestions?

Each state needs to be defined in it's own .state() method. You will run into multiple problems trying to do it the way you listed above. Most importantly would be the url.
You can simply do this:
.state('parent.list', {
url: '/list',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
.state('parent.list.details', {
url: '/:id/:name',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
})
While the code is not condensed or efficient in the sense you have to declare the controller and partial used on each state, it is necessary because each state needs its own .state() method

I wanted the same and made it like this:
//add a new Function to the object $stateProvider
$stateProvider.states = (statesArr, obj) => {
for (var i in statesArr) {
var state = statesArr[i];
$stateProvider.state(state, obj);
}
return $stateProvider;
};
//use the new function
$stateProvider
.states(["main", "main.test"], {
url: '/main',
templateUrl: 'modules/ViewContainer.html',
controllerAs: 'currentCtrl',
controller: 'MainCtrl'
})

Related

ui-router child views not running controller

Trying to get the following url structure to work:
/page/
/page/article
/page/article/third-level-1
/page/article/third-level-2
Ive tried the follow but it doesn't render the article view at all. The page view renders fine:
<section ui-view></section>
$stateProvider
.state('index', {
external: true,
url: '/'
})
.state('page', {
url: '/page',
controller: Controller,
controllerAs: 'ctrl',
templateUrl: '/static/views/page/page.html',
})
.state('page.article', {
url: '/article/',
controller: Controller,
controllerAs: 'ctrl',
templateUrl: '/static/views/page/page-article.html'
});
I then tried everything under the sun, and managed to get the second view to render with the following, however the Controller doesnt run on the article view:
<section ui-view="app"></section>
$stateProvider
.state('index', {
external: true,
url: '/'
})
.state('page', {
url: '/page',
views: {
'app': {
controller: Controller,
controllerAs: 'ctrl',
templateUrl: '/static/views/page/page.html',
}
}
})
.state('page.article', {
url: '/article/',
views: {
'app#': {
controller: Controller,
controllerAs: 'ctrl',
templateUrl: '/static/views/page/page-article.html',
}
}
});
How can i get the child view to render and use the/a controller? Haven't even gotten down to the third level.
It should be this.
.state('page.article', {
url: '/page/article/',
views: {
'app#': {
controller: Controller,
controllerAs: 'ctrl',
templateUrl: '/static/views/page/page-article.html',
}
}

Calling view of other state Angularjs

i am with doubt of like i call an view inside of other view. I want call the view " menu " in side of state "login" . However is not working
$stateProvider
.state('menu', {
abstract:true,
views: {
"menu": {
templateUrl: 'assets/templates/menu/menu.html',
controller: 'MenuController',
}
}
})
.state("login", {
url: '/login',
views: {
"": {
templateUrl: 'assets/templates/LoginTest.html',
controller: 'LoginController as ctrl',
},
"#menu":{ }
}
});
You need to use nested state for that.
This tutorial will help you AngularJS Multi-Step Form Using UI Router
working plunkr :https://plnkr.co/edit/ar9kbBCdggZxvUGDq5HI?p=preview
$stateProvider
.state('login', {
abstract:true,
url: '/login',
templateUrl: 'assets/templates/LoginTest.html',
controller: 'LoginController as ctrl'
})
// nested states
// each of these sections will have their own view
// url will be nested (/login/menu)
.state("login.menu", {
url: '/menu',
templateUrl: 'assets/templates/menu.html',
controller: 'MenuController'
}
);

Angular ui router -pass stateParams to other controller

This is part of my state provider:
$stateProvider.state('root', {
url: '',
abstract: true,
templateUrl: viewsRoot + "layout.html",
controller: 'LayoutController',
views: {
'container': {
templateUrl: viewsRoot + "container.html",
},
'sidebar': {
templateUrl: viewsRoot + "sidebar.html",
controller: 'SidebarController'
}
}
})
.state('layout.sidebar', {
abstract: true,
templateUrl: viewsRoot + "sidebar.html",
controller: 'SidebarController'
})
.state('layout.container', {
abstract: true,
templateUrl: viewsRoot + "container.html",
// controller: 'ObjectDetailsController'
})
.state('root.object-details', {
url:'object-details/:objectId',
templateUrl: viewsRoot + "object-details.html",
controller: 'ObjectDetailsController',
Some content on sidebar should change depending on objectId. I can access $stateParams.objectId in ObjectDetailsController but I would like to access them in sidebar controller. Maybe pass them to parent, and then parent should pass value to sidebar.
Did you try to pass the data via the params options in $stateProvider?
The API can be found here.
So your code can look like this:
.state('layout.sidebar', {
abstract: true,
templateUrl: viewsRoot + "sidebar.html",
controller: 'SidebarController',
params: {id: 'value'}
})
You can pass the param inside the view:
<a ui-sref="layout.sidebar({id: 'object.Id'})></a>

Access $routeparams from abstract state

Is it possible to access $routeParams in this case the id parameter within the abstract ProfileCtrl?
.state('profile', {
abstract: true,
url: "/profile",
templateUrl: 'profile.html',
controller: 'ProfileCtrl'
})
.state('profile.items', {
url: "/:id/items",
views: {
'profile': {
templateUrl: 'ProfileItems.html',
controller: 'ProfileItemsCtrl'
}
}
})
ProfileCtrl can only get parameters of it's url. Use the following:
.state('profile', {
abstract: true,
url: "/profile/:id",
templateUrl: 'profile.html',
controller: 'ProfileCtrl'
})
.state('profile.items', {
url: "/items",
views: {
'profile': {
templateUrl: 'ProfileItems.html',
controller: 'ProfileItemsCtrl'
}
}
})
This way ProfileCtrl is able to get the profile id. It can fetch the profile data and attach it to the $scope. This way any child of profile state will have access to the profile data (due to $scope inheritance).
Hope this helps!

Angular: inheriting view in states

In Angular/Ionic i have three different states:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('layout', {
url: "",
abstract: true,
templateUrl: "templates/base/layout.html"
})
.state('layout.home', {
url: "/home",
views: {
'mainContent' :{
templateUrl: "templates/home.html"
},
'leftMenuContent' :{
controller: "LeftMenuController",
templateUrl: "templates/left-menu.html"
}
}
})
.state('layout.about', {
url: "/about",
views: {
'mainContent' :{
templateUrl: "templates/about.html",
controller: "AboutController"
},
'leftMenuContent' :{
controller: "LeftMenuController",
templateUrl: "templates/left-menu.html"
}
}
})
So i have an abstract state which defines the base/main layout, home and about states which have two views: mainContent and leftMenuContent. As for the LeftMenuController functionality, it just returns custom options for every route depending the $state.current.name.
As leftMenuContent will be the same for every state, is there any way to avoid defining it in every new state and inheriting it from the layout state (or somewhere else) instead?
You are almost there: By calling the state layout.home it will inherit its views from layout, so this should work:
.state('layout', {
url: "",
abstract: true,
templateUrl: "templates/base/layout.html",
views: {
'leftMenuContent' :{
controller: "LeftMenuController",
templateUrl: "templates/left-menu.html"
}
}
})
.state('layout.home', {
url: "/home",
views: {
'mainContent' :{
templateUrl: "templates/home.html"
}
}
})
.state('layout.about', {
url: "/about",
views: {
'mainContent' :{
templateUrl: "templates/about.html",
controller: "AboutController"
}
}
})
This is what I found to be working to show nested views.
So, I have a main view in which I display my home template (<ui-view> in index.html), in the home template I have another <ui-view> in which I call different states based on what I want.
config(function config($stateProvider) {
$stateProvider
.state('sidemenu.home', {
url: '/home',
views: {
'topView': {
controller: 'HomeCtrl',
templateUrl: 'home/home.tpl.html'
}
}
})
.state('sidemenu.home.list', {
templateUrl: 'home/home-list.tpl.html'
/*,controller: 'HomeCtrl'*/
})
.state('sidemenu.home.login', {
templateUrl: 'home/home-login.tpl.html'
/*,controller: 'HomeCtrl'*/
})
.state('sidemenu.home.register', {
templateUrl: 'home/home-register.tpl.html'
/*,controller: 'HomeCtrl'*/
})
.state('sidemenu.home.coach', {
templateUrl: 'home/home-coach.tpl.html'
/*,controller: 'HomeCtrl'*/
})
;
})
.controller('HomeCtrl', function HomeController($scope, $rootScope, $state) {
/**
* ===== FIRST LOGIC =====
**/
//Redirect the user to the appropriate page.
switch ($rootScope.tellState()) {
case "ok-local":
$state.transitionTo('sidemenu.home.list');
break;
case "register":
$state.transitionTo('sidemenu.home.register');
break;
case "login":
$state.transitionTo('sidemenu.home.login');
break;
case "coach":
$state.transitionTo('sidemenu.home.coach');
break;
}

Resources