Angular UI-Router nested state template not rendered - angularjs

I'm new to ui-router and can't get layout.directory.teams or layout.directory.people to load their respective templates. I expect those templates to be loaded in the ui-viewon the layout state's template.
/dashboard works fine...the dashboard.html template is loaded in the ui-view in content.html template.
/directory/teams doesn't load the teams.html template.
/directory/people doesn't load the people.html template.
.state('layout', {
abstract: true,
templateUrl: "components/common/content.html"
})
.state('layout.dashboard', {
url: "/dashboard",
controller: 'DashboardCtrl',
controllerAs: 'dashboard',
templateUrl: "app/features/dashboard/views/dashboard.html",
})
.state('layout.directory', {
abstract: true,
url: "/directory"
})
.state('layout.directory.teams', {
url: "/teams",
controller: 'DirectoryCtrl',
controllerAs: 'directory',
templateUrl: "app/features/directory/views/teams.html",
})
.state('layout.directory.people', {
url: "/people",
controller: 'DirectoryCtrl',
controllerAs: 'directory',
templateUrl: "app/features/directory/views/people.html",
})

A child state renders its template in the template of its parent where ui-view directive is, even if the parent is abstract.
So, in your case, add ui-view to the template of layout.directory state:
.state('layout.directory', {
abstract: true,
url: "/directory",
template: "<div ui-view></div>"
})

Related

angular nested state uirouter not loading template

With the following code, I'm trying to create a page with the url /admin, that would lead you to /admin/devices after clicking a button and after clicking another button to /admin/devices/new. The first part works properly and I get redirected to /admin/devices. The second part not quite, since it changes the url to /admin/devices/new but it doesn't change the template.
To change through url's I use $state.go(admin.devices) and $state.go(admin.devices.new)
Any idea?
$stateProvider
.state('admin', {
url: '/users',
abstract: true
})
.state('admin.devices', {
url: '/devices',
template: require('../templates/admin/devices/index.html'),
controller: 'AdminDevicesCtrl',
controllerAs: 'ctrl'
})
.state('admin.devices.new', {
url: '/new',
template: require('../templates/admin/devices/new.html'),
controller: 'AdminDevicesNewCtrl',
controllerAs: 'ctrl'
});

Nested templates using ui-view

I'm trying to display a nested template using ui-view.
AngularJS routing config
angular.module('myApp')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('home', {
url: '',
abstract: true
})
.state('home.default', {
parent: 'home',
url: '/home',
data: {
pageTitle: 'Homepage'
},
views: {
'content#': {
templateUrl: 'app/default/default.html',
controller: 'defaultController',
controllerAs: 'defaultController'
}
}
})
.state('default.subview', {
parent: 'default',
url: '/default/subview',
data: {
pageTitle: 'Homepage - subview'
},
views: {
'content#': {
templateUrl: 'app/subview/subview.html',
controller: 'subviewController',
controllerAs: 'subviewController'
}
}
})
;
}]);
Home: /#/home
<!-- this URI should be #/home -->
<h2>Homepage</h2>
<select>
<option>Subview</option>
</select>
<hr>
<!-- nested subview -->
<div ui-view=""></div>
Subview: /#/home/subview
<h2>Subview</h2>
So basically, I want the parent view (home) and subview's content to be included when I visit (/#/home/subview). However, only the subview content is being displayed.
Any tips on how to correctly utilize ui-view and nested subviews in AngularJS?
Your subview has to be a child of home and you set the subview with 'content#' to an defined ui-view wich replaces your view from home.
And I edited some copy paste issue since it looks like your home route was called default before
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('home', {
url: '/home',
abstract: true,
template: '<ui-view/>'
})
.state('home.default', {
url: '/home/default',
data: {
pageTitle: 'Homepage'
},
views: {
'': {
templateUrl: 'home.html',
controller: 'defaultController',
controllerAs: 'defaultController'
}
}
})
.state('home.subview', {
parent: 'home',
url: '/subview',
data: {
pageTitle: 'Homepage - subview'
},
views: {
'': {
templateUrl: 'subview.html',
controller: 'subviewController',
controllerAs: 'subviewController'
}
}
});
}]);
Edit:
I created a Plunker with an working configuration, there was some more issues with that abstract home state (I never get it to work as expected) but if you click the links everything appears as expected.
Plunker
There really is no need for the views section if you have only one ui-view
angular.module('myApp')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('home', {
url: '',
abstract: true,
template: '<ui-view></ui-view>'
})
.state('home.default', {
// parent: 'home', // No need to set parent if you already prefixed state name
url: '', // The default subview of an abstract view should have '' for url
data: {
pageTitle: 'Homepage'
},
templateUrl: 'app/default/default.html',
controller: 'defaultController',
controllerAs: 'defaultController'
})
.state('home.default.subview', {
// parent: 'default', // No ned for parent
url: '/subview', // Only pu the part of the url here that is added to the parent'ls url
data: {
pageTitle: 'Homepage - subview'
},
templateUrl: 'app/subview/subview.html',
controller: 'subviewController',
controllerAs: 'subviewController'
})
;
}]);
In addition I've also changed the ui-sref in index.html
<a ui-sref="home.default.subview">Subview Route</a>
And the ui-view in home.html
<!-- nested subview -->
<ui-view></ui-view>
Check this plunker:
https://plnkr.co/edit/vEDYvXhp5mNjVT0yLRJN?p=preview

angular state: abstract: true, how can I tell a child to not use parent template

Is it possible to tell a specific child to not use the parent html template using abstract set to true ?
$stateProvider
.state('contacts', {
abstract: true,
url: '/:my_id/contacts',
templateUrl: 'contacts.html'
})
.state('contacts.list', {
url: 'list',
// loaded into ui-view of parent's template
templateUrl: 'contacts.list.html'
})
.state('contacts.detail', {
url: 'detail',
'dontUseParentTemplate': true, // something like that
// loaded into ui-view of parent's template
templateUrl: 'contacts.detail.html'
})

How to display ui-router state on whole page?

I'm using ui-router for state handling. This works fine, but now I have to create page 404 and would like to display it on the whole page and not inside the page as other pages.
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function ($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.hashPrefix('!').html5Mode({
enabled: true,
requireBase: false
});
$stateProvider
.state('stateIndex', {
url: '/',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
.state('stateList', {
url: '/list',
templateUrl: '/templates/list.html',
controller: 'dashListController'
}).state('stateDashboard', {
url: '/dashboard/:id',
templateUrl: '/templates/dashboard.html',
controller: 'dashboardController'
})
.state('stateWidgetsList', {
url: '/widgetsList',
templateUrl: '/templates/widgetsList.html',
controller: 'widgetsListController'
})
.state('404', {
url: '/404',
templateUrl: '/templates/404.html'
});
}]);
and on my index.html I have
<div ui-view></div>
where I display all the pages, outside of this I have logo, menu, etc.. which I would like to hide while displaying 404 page.
How can I do it?
Personally I would redesign the index.html, and bring the outer template (logo, menu, etc), into it's own template and state. Then you can sit child states below it in the ui-router hierarchy. For example:
$stateProvider
.state('app', {
abstract: true,
url: '',
templateUrl: '/templates/appcontainer.html'
})
.state('app.stateIndex', {
url: '/',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
.state('404', {
url: '/404',
templateUrl: '/templates/404.html'
});
Then you just need to put your logos/menus, etc inside appcontainer.html, and then just have a single <div ui-view></div> inside your index.html. Also if you do it this way, don't forget to add the child ui-view inside appcontainer.html.
You can create a root parent state that will contain your layout stuff (logo, menu, etc) and have the 404 live outside of that.
routes
$stateProvider
.state('root', {
abstract: true, // makes this state not directly accessible
templateUrl: 'root.html'
})
.state('root.stateIndex', {
url: '/',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
// ...
.state('404', {
url: '/404',
templateUrl: '/templates/404.html'
});
root.html
<nav><!-- menu stuff --></nav>
<ui-view></ui-view>
<footer></footer>

Defaulting to Angular UI-Router Nested View

I am trying to open the state 'profile.general' by default when I navigate to the parent state profile which loads the main template.
How do I activate the nested state for the ui-view when the /profile url is navigated to?
$urlRouterProvider.otherwise("/profile/general");
$stateProvider.state('profile', {
url: '/profile',
abtract: true,
views: {
"main": {
controller: 'ProfileCtrl',
templateUrl: 'src/app/profile/index.tpl.html'
}
}
}).state('profile.general', {
//url: '/register/details',
templateUrl: 'src/app/profile/profile-general.html'
//controller: 'ProfileCtrl'
}).state('profile.security', {
//url: '/register/details',
templateUrl: 'src/app/profile/profile-security.html'
}).state('profile.social', {
//url: '/register/details',
templateUrl: 'src/app/profile/profile-social.html'
}).state('profile.privacy', {
//url: '/register/details',
templateUrl: 'src/app/profile/profile-privacy.html'
}).state('profile.payments', {
//url: '/register/details',
templateUrl: 'src/app/profile/profile-payments.html'
}).state('profile.restrictions', {
//url: '/register/details',
templateUrl: 'src/app/profile/profile-restrictions.html'
});
})
HTML
<div id="profile-views" ui-view></div>
There is a working plunker
These lines should help:
$urlRouterProvider.when("/profile", "/profile/general");
$urlRouterProvider.otherwise("/profile/general");
And we should give url to the general sub state:
.state('profile.general', {
//url: '/register/details',
url: '/general',
templateUrl: 'src/app/profile/profile-general.html'
So, with these in place, we have .when redirection... which whenever user is targeting just the abstract state - does redirect to selected url.
Also, because we introduced the url for a child, we can use the .otherwise as the overall default state.
Other way how to do that, is to omit the url of one child (just exactly one child):
How to: Set up a default/index child state
Check it here

Resources