I have a UI-Router document set up to show the "pages" sections of a demo.
(function() {
'use strict';
angular.module('pb.ds.pages').config(function($stateProvider) {
$stateProvider.state('pages', {
abstract: true,
url: '/pages',
templateUrl: 'modules/pages/templates/pages.html',
controller: 'PagesController as pages',
data: {
pageTitle: 'Pages',
access: 'public',
bodyClass: 'pages'
}
})
.state('pages.signin', {
url: '/signin',
templateURL: 'modules/pages/templates/signin.html',
controller: 'SignInController as signin'
})
.state('pages.forgotpassword', {
url: '/forgotpassword',
templateURL: 'modules/pages/templates/forgotpassword.html',
controller: 'ForgotPasswordController as forgot'
})
.state('pages.404', {
url: '/404',
templateURL: 'modules/pages/templates/404.html',
controller: '404Controller'
});
});
})();
The parent state, "pages" has the ui-view on it, but otherwise I don't need to "show" it. I am only interested in showing its children, such as pages.signin or pages.forgotpassword.
Typing in the url "/forgotpassword" bounces me back to my homepage, which is the "otherwise" state in my app.module.js
// UI ROUTER CONFIG
angular.module('app').config(function($stateProvider) {
$stateProvider.state('otherwise', {
url: '*path',
template: '',
controller: function($state) {
$state.go('dashboard');
}
});
});
No errors in console, and all the pages in question are linked in my index.html.
I'm sure I must have missed something obvious. Any clues?
UPDATE
If I enter /pages/forgotpassword it does go to the correct path but the view is not being populated by the template...
There is a working plunker
We have to adjust state definition like this:
$stateProvider.state('pages', {
abstract: true,
//url: '/pages',
templateUrl: 'modules/pages/templates/pages.html',
controller: 'PagesController as pages',
data: {
pageTitle: 'Pages',
access: 'public',
bodyClass: 'pages'
}
})
.state('pages.signin', {
url: '/signin',
// templateURL: 'modules/pages/templates/signin.html',
templateUrl: 'modules/pages/templates/signin.html',
controller: 'SignInController as signin'
})
.state('pages.forgotpassword', {
url: '/forgotpassword',
//templateURL: 'modules/pages/templates/forgotpassword.html',
templateUrl: 'modules/pages/templates/forgotpassword.html',
controller: 'ForgotPasswordController as forgot'
})
The most important is replacement of the templateURL with templateUrl. Javascript (and UI-Router) is case sensitive.
We also do not need define url for parent... it could be just child state definition
Finally, we must be sure, that our parent contains some target ui-view="" where child states will be placed. E.g. this is the plunker pages.html:
<div>
<h3>pages</h3>
<hr />
<div ui-view=""></div>
</div>
These links will then work as expected:
//href
<a href="#/signin">
<a href="#/forgotpassword">
//ui-sref
<a ui-sref="pages.signin">
<a ui-sref="pages.forgotpassword">
We can leave the parent url:
$stateProvider.state('pages', {
abstract: true,
url: '/pages',
...
but the href links for child states must contain the parent url as well:
<a href="#/pages/signin">
<a href="#/pages/forgotpassword">
Check it here in action
You need to prefix the state url with the url of the parent state. So the correct url that you need open with the browser should be: #/pages/forgotpassword
Check the doc URL Routing for Nested States
Related
I am attempting to set up nested views loading in the parent views via state children but I'm not sure if I'm going about this the correct way.
So far, I have:
$stateProvider
.state('splash', {
url: '/splash',
templateUrl: 'system/templates/splash.html',
controller: ""
}).state('home', {
url: '/',
templateUrl: 'system/templates/home.html',
controller: ""
}).state('user', {
url: '/user/:user?',
templateUrl: 'system/templates/user.html',
controller: "userController"
}).state('user.data', {
views: {
"#vdata" : {
templateUrl: 'system/templates/user.html',
controller: "userController"
}
}
})
The "user" parent state recieves :user? the correct way, however when I try to navigate via $state.transitionTo();, I get the response of
Param values not valid for state 'user.data'. I have an unnamed view with the pattern
<div ui-view></div>
set as the parent. Then nested in the user template, I have a ui-view called "vdata". According to the documentation, if I target #vdata, the pages requested should be loading there.
How can I get the nested view to inherit the parameter from the parent view?
Use resolve and inject user on controller. The resolved references are shared betwen parent child states.
$stateProvider
.state('splash', {
url: '/splash',
templateUrl: 'system/templates/splash.html',
controller: ""
}).state('home', {
url: '/',
templateUrl: 'system/templates/home.html',
controller: ""
}).state('user', {
url: '/user/:user?',
templateUrl: 'system/templates/user.html',
controller: "userController",
resolve:{
user: function($stateparams){
return $stateParms.user;
}
}
....
On usercontroller inject user
I'm trying to create a nav bar with 3 links
I would like to get page.1 at the first time without clicking on page.1 ui-sref,
i have like html:
<nav>
<a ui-sref="page.1">Search</a>
<a ui-sref="page.2">Results</a>
<a ui-sref="page.3">Detail</a>
</nav>
<ui-view></ui-view>
My states are defined as follows:
angular.module('scrollDemo', ['ui.router'])
.config(function($stateProvider) {
$stateProvider
.state('page.1', {
url: '/page1',
templateUrl: '/Page1.html'
})
.state('page.2', {
url: '/page2',
templateUrl: '/Page2.html'
})
.state('page.3', {
url: '/page3',
templateUrl: '/Page3.html'
});
})
How can i procced ?
you can use $urlRouterProvider.otherwise('/path'); to set the detault path.
angular.module('scrollDemo', ['ui.router'])
.config(function($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise('/page.1');
$stateProvider
.state('page.1', {
url: '/page1',
templateUrl: '/Page1.html'
})
.state('page.2', {
url: '/page2',
templateUrl: '/Page2.html'
})
.state('page.3', {
url: '/page3',
templateUrl: '/Page3.html'
});
})
You seem like you want to immediately go to /page.1 when your application is loaded, what you can do is the following :
angular.module('scrollDemo', ['ui.router'])
.run(function($location) {
$location.path('/page1');
});
This will automatically change the path of your application to the desired one right after everything is loaded.
I am struggling to create a container for next states, defined the states as views, divided into header, CONTAINER, footer.
The next state as an example would be the blogs, but I do not see a way of getting it into the view.
One idea was to start the HOME view as standard, but also failed.
view:
<main>
<header ui-view="header"></header>
<content ui-view="home"></content>
<footer ui-view="footer"></footer>
</main>
states:
.state('home',{
url:'/',
data: {
pageTitle: 'Home'
},
views: {
'': {
templateUrl: 'content/index.html',
},
'header#home': {
templateUrl: 'content/templates/header.html',
controller: 'HeaderController',
cache: false
},
'home#home': {
templateUrl: 'content/templates/home.html',
controller: 'IndexController',
cache: false
},
'footer#home': {
templateUrl: 'content/templates/footer.html',
//controller: 'FooterController',
cache: false
}
}
})
.state('home.blog',{
url : '/blog',
templateUrl : 'content/templates/blog.html',
controller : 'BlogController',
data: { pageTitle: 'Blog' },
access: {requiredLogin: false}
})
SUCCESS! :)
Plunker Example: http://plnkr.co/edit/yRgqiAeEVQl2WVajGgG0?p=preview
In the updated question above, you've used this plunker to show how you made it working:
.state('home',{
url:'',
abstract: true,
views: {
'': {
templateUrl: 'index.html' // this
},
'header#home': {
templateUrl: 'header.html'
},
'footer#home': {
templateUrl: 'footer.html'
}
}
})
.state('home.index',{
url : '/',
templateUrl : 'home.html'
})
.state('home.blog',{
url : '/blog',
templateUrl : 'blog.html',
});
While that solution is working, it is in fact not a way you/we should go. Because the parent state 'home', injects into unnamed view itslef - templateUrl: 'index.html'
So, now there are again views header and footer, but they do differ from the root (original index.htm). Their absolute name would be 'header#home' and 'footer#home' (as used int the code snippet) - and all seems to be working.
But that is redundant. Unless we will move the layout into some 'layout' state and 'layout.html'
Angular UI Router - Nested States with multiple layouts
Nested states or views for layout with leftbar in ui-router?
Why redundant? Because index.html already is in play (as a root) and it contains these targets. their absolute name is 'header#' and 'footer#'. And that should be the way to go.
To make it clear, there is an updated plunker and its snippets:
.state('home',{
url:'',
abstract: true,
views: {
'': {
template: '<div ui-view=""></div>'
},
'header': {
templateUrl: 'header.html'
},
'footer': {
templateUrl: 'footer.html'
}
}
})
.state('home.index',{
url : '/',
templateUrl : 'home.html'
})
.state('home.blog',{
url : '/blog',
templateUrl : 'blog.html',
});
Check the update here
I am creating a web app to help students in science, history and math. When you first land on the site I have a home/landing page. When you click get started I route to /exam/instructions. Each of my steps instructions, math and science our templates that I load into the ui-view="exam-detail". Currently the whole ui-view loads when I navigate to and from instructions through sciences. Ideally I simply want an area for pagination and an area for the subject matter and only want the ui-view="exam-detail" to update with the correct template.
I have not used UI-Router at all and any assistance would be greatly appreciated.
index.html
<div ui-view></div>
state-exam>exam.html
<div class="state-exam">
<nav ui-view="exam-pagination"></nav>
<section ui-view="exam-detail"></section>
</div>
route.js
(function() {
'use strict';
angular
.module('studentPortal')
.config(routeConfig);
function routeConfig($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'main'
})
.state('exam', {
url: '/exam/:step',
abstract: true,
templateUrl: 'app/state-exam/exam.html',
controller: 'ExamController',
controllerAs: 'examController',
})
.state('exam.instructions', {
url: '/instructions',
views: {
'exam-pagination':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
'exam-detail' : {
templateUrl: 'app/state-exam/exam-instructions.html'
}
}
})
.state('exam.math', {
url: '/math',
views: {
'exam-pagination':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
'exam-detail' : {
templateUrl: 'app/state-exam/exam-math.html'
}
}
});
$urlRouterProvider.otherwise('/');
}
})();
There is a working plunker
There is a similar Q & A in fact, with working plunker:
Angular UI Router - Nested States with multiple layouts
Solution here, is to move the static view from child to parent. It won't be reloaded for each child (view is reloaded only if parent state is changed). We will use absolute naming (see included links for more details)
So this is the code adjustment
.state('exam', {
url: '/exam/:step',
abstract: true,
// the root view and the static pagination view
// will be defined here, so we need views : {}
views: {
'':{
templateUrl: 'app/state-exam/exam.html',
controller: 'ExamController',
controllerAs: 'examController',
},
// absolute naming targets the view defined above
'exam-pagination#exam':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
}
})
.state('exam.instructions', {
url: '/instructions',
views: {
// 'exam-pagination':{}, // defined in parent
'exam-detail' : {
templateUrl: 'app/state-exam/exam-instructions.html'
}
}
})
.state('exam.math', {
url: '/math',
views: {
// 'exam-pagination':{}, // defined in parent
'exam-detail' : {
templateUrl: 'app/state-exam/exam-math.html'
}
}
});
Also check this to get more details about absolute view naming
Angular UI router nested views
Angular-UI Router: Nested Views Not Working
The working example is here
I'm try to use ui-router to manage nested views on a single page app.
Let's say I want to create a dashboard application with a common area and multiple views.
The main and the nested states are handled like this:
$stateProvider.state('home', {
url: '/',
template: 'MY HOME PAGE'
})
.state('login', {
url: '/login',
templateUrl: '/pages/login.html'
})
.state('registration', {
url: '/registration',
templateUrl: '/pages/registration.html'
})
.state('dashboard', {
url: '/dashboard',
templateUrl: '/pages/dashboard/dashboard.html'
})
.state('dashboard.me', {
url: '/me',
templateUrl: '/pages/dashboard/me.html'
})
.state('dashboard.messages', {
url: '/messages',
templateUrl: '/pages/dashboard/messages.html'
})
.state('dashboard.friends', {
url: '/friends',
templateUrl: '/pages/dashboard/friends.html'
});
The dashboard HTML page is the following:
<div class="container" ng-controller="dashboardCtrl" ng-init="init()">
<h2>DASHBOARD</h2>
<ul>
<li><a ui-sref="dashboard.me">Me</a></li>
<li><a ui-sref="dashboard.messages">My Messages</a></li>
<li><a ui-sref="dashboard.friends">My Friends</a></li>
</ul>
<div ui-view></div>
The above HTML is also included inside an ui-view.
Everything works fine if I navigate my application using the anchors.
By the way if I try to go directly to myhost/dashboard/me or myhost/dashboard/friends (every path with two levels of nested views) the app doesn't work. I get an angular (unexpected token <) but I don't think it's relevant...
It seems like it's not able to resolve the first level of nested view.
The following images show the HTML obtained when the navigation is done using anchors:
and the HTML obtained when the page is called directly from the browser address link:
Any ideas? Thanks.
The problem is that angular is not loading, hence the error. The code looks correct to me though, unless you missed the closing tag for
<div class="container" ng-controller="dashboardCtrl" ng-init="init()">
?
JavaScript State Configurations :
$stateProvider.state('home', {
url: '/',
template: 'MY HOME PAGE'
})
.state('login', {
url: '/login',
templateUrl: '/pages/login.html'
})
.state('registration', {
url: '/registration',
templateUrl: '/pages/registration.html'
})
.state('dashboard', {
url: '/dashboard',
abstract: true,
parent: 'home',
templateUrl: '/pages/dashboard/dashboard.html'
})
.state('dashboard.me', {
url: '/me',
views: {
'#dashboard_view': {
templateUrl: '/pages/dashboard/me.html'
}
}
})
.state('dashboard.messages', {
url: '/messages',
views: {
'#dashboard_view': {
templateUrl: '/pages/dashboard/messages.html'
}
}
})
.state('dashboard.friends', {
url: '/friends',
views: {
'#dashboard_view': {
templateUrl: '/pages/dashboard/friends.html'
}
}
});
Dashboard HTML
<div class="container" ng-controller="dashboardCtrl" ng-init="init()">
<h2>DASHBOARD</h2>
<ul>
<li><a ui-sref="dashboard.me">Me</a></li>
<li><a ui-sref="dashboard.messages">My Messages</a></li>
<li><a ui-sref="dashboard.friends">My Friends</a></li>
</ul>
<div ui-view="dashboard_view"></div>
You can get more details:
Multiple Named Views
Nested States and Nested Views