I have the following code snippet:
$stateProvider.state('unlogged', {
url: '/',
templateUrl: 'unlogged/unlogged.html'
}).state('sign-in', {
parent: 'unlogged',
url: '/sign-in',
templateUrl: 'sign-in/sign-in.html',
controller: 'SignInCtrl'
}).state('sign-up', {
parent: 'unlogged',
url: '/sign-up',
templateUrl: 'sign-up/sign-up.html',
controller: 'SignUpCtrl'
});
When I go to /sign-up, it is not loading the parent nor the child.
My HTML when I inspect the page: <section ui-view="" class="ng-scope"></section>
unlogged.html has the ui-view directive: <div class="row" ng-class="{slide : effect}" ui-view></div>
There is a working example
To make child state url working without parent part, we need to reset that url mapping with a sign ^:
.state('sign-in', {
parent: 'unlogged',
url: '^/sign-in',
...
})
.state('sign-up', {
parent: 'unlogged',
url: '^/sign-up',
...
});
Check it in action here
Maybe also observe this:
angular ui-router parent url set to /
Related
I'm trying to set my application to works with 2 layouts (one without sidebars, one with 2 sidebars), this is my solution:
$stateProvider
.state('main', {
url: "/",
abstract:true,
templateUrl: "/layouts/main.html"
})
.state('sidebars', {
url: "/",
abstract:true,
templateUrl: "/layouts/two-sidebar.html"
})
.state('home', {
parent:'main',
templateUrl: "/partials/home.html"
})
.state('about', {
url: "about",
parent:'sidebars',
templateUrl: "/partials/about.html"
})
main.html
<div class="container">
<div ui-view class="view"/>
</div>
two-sidebar.html
<div class="container-fluid">
<div class="row">
<div class="col-md-2">leftcontent</div>
<div class="col-md-8">
<div ui-view class="view"></div>
</div>
<div class="col-md-2">rightcontent</div>
</div>
</div>
I'm sure there are better solutions, but with this all works fine.
The only problem is when I visit the root page /#/ the first time I get a blank page, when I click on home the url is the same but it works fine.
To be more clear, here the plunker, to see the problem you have to open it in an external windows (the blue button in the preview window): http://plnkr.co/edit/Q4cZM69hn0lutYEYjmxH?p=preview
EDIT: It looks like the main problem was the missing empty url
.state('home', {
url:"",
parent:'main',
templateUrl: "/partials/home.html"
})
You have defined two states bound to the same URL (/).
According to UI Router's design, only one state should be bound to a URL.
If you want to have two states with the same URL, make the second one the child state and let it have nothing in it's URL prop like so:
.state('main', {
url: "/",
abstract:true,
templateUrl: "/layouts/main.html"
})
.state('main.sidebars', {
url: "",
templateUrl: "/layouts/two-sidebar.html"
})
Change it like this,
.state('main', {
url: "/",
abstract:true,
templateUrl: "/layouts/main.html"
})
.state('sidebars', {
url: "/something",
abstract:true,
templateUrl: "/layouts/two-sidebar.html"
})
I have a basic Index.html file which following structure:
<body class="{{$state.current.name.replace('.','-')}}">
<div ui-view>
<div ng-include src="'partials/menu.html'"></div>
<!-- <div ng-menu class="ui top blue sidebar menu active"></div> -->
<div class="view-height-100"></div>
</div>
...
</body>
When I am in the login state, it's working very well:
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'partials/login-area.html',
controller: 'LoginController',
});
But, when I am routing to the user.management state, nothing gets shown (but Chrome is loading the template, so I can access the scope and the .html file is there):
$stateProvider
.state('user', {
url: '/:buildingName',
controller: 'CurrentBuildingController',
data: {
access: ['user']
}
})
.state('user.management', {
url: '/management',
templateUrl: '/views/management.html',
controller: 'ManagementController'
})
Can someone explain me why?
Parent state simply must have target for its child (unless we use absolute naming to target some super parent, but it is another approach)
.state('user', {
url: '/:buildingName',
template: "<div ui-view></div>",
controller: 'CurrentBuildingController',
data: {
access: ['user']
}
})
see that we now have template: "<div ui-view></div>", which will serve as a view target for any child state 'user.xxx'
Check also:
AngularJS UI-Router : Abstract state + child states not working
EXTEND - let child to target the index.html
We can use absolute naming and child will then be injected directly into index.html. There is a working plunker (by intention parent won't load, it does not have any template)
.state('parent', {
url: "/parent",
//templateUrl: 'tpl.html',
})
.state('parent.child', {
url: "/child",
views: {
'#': {
templateUrl: 'tpl.html',
controller: 'ChildCtrl',
}
}
})
Check this for more info:
Angularjs ui-router not reaching child controller
Angular version: 1.3.17
UI-Router version: 0.2.15
angular.module('demoApp')
.config(function ($stateProvider) {
$stateProvider
.state('admin', {
url: '/admin',
templateUrl: 'app/admin/admin.html',
controller: 'AdminCtrl'
})
.state('admin.category', {
url: '/category',
templateUrl: 'app/admin/category/category.html',
controller: 'CategoryCtrl'
})
})
For some reason the child admin.category state never activates when I visit /admin/category. I can see no reason why it should not work, any help would be much appreciated.
It is because your admin state should be abstract like this:
.state({
name: 'admin',
templateUrl: 'app/admin/admin.html',
controller: 'AdminCtrl',
abstract: true
})
For child states to be active, ui-router expects that the parent state's template will contain a <ui-view/> tag that will load the child state. I forgot to put the tag in the template hence the child controller was never getting activated.
I've looked at countless examples of how to set this up. Many right here at SO. But nothing is working in my case. It's a very simple set of two views, one nested below the first. Second ui-view never loads...
Here is the simple index.html...
<body ng-app="d6Games">
<div ui-view="home"></div>
</body>
Here is the simple child view, this is inside home.html template...
<div class="d6body bilbo">
<div ui-view="content"></div>
</div>
Here are the simple states...
.state('home', {
url: '/home',
views: {
'home': {
templateUrl: '/views/home.html'
}
}
})
.state('home.intro', {
url: '/intro',
views: {
'content': {
templateUrl: '/views/game-intro.html'
}
}
})
The first /views/home.html template loads fine, as expected, however the child /views/game-intro.html never loads. It's just html and text and it's in the same folder as home.html.
What am I missing?
There is a working plunker
I just changed the template path (removed the leading '/'), and all is working (however this was required for plunker, not sure about your environment and path settings):
$stateProvider
.state('home', {
url: '/home',
views: {
'home': {
templateUrl: 'views/home.html'
}
}
})
.state('home.intro', {
url: '/intro',
views: {
'content': {
templateUrl: 'views/game-intro.html'
}
}
})
}
Check that in action here
(AngularJS v1.2.0-rc.3 + Angular UI-Router v0.2.0)
In my index.html, I have the following code:
<div class="container" ui-view></div>
In my app.js, I have the following code:
$stateProvider
.state('projects', {
abstract: true,
url: '/projects',
template: '<ui-view />',
})
// below display properly
.state('projects.list', {
url: '',
templateUrl: 'views/project_list.html',
controller: 'ProjectListCtrl'
})
// below display properly
.state('projects.one', {
url: '/{projectId:[0-9]{1,8}}',
templateUrl: 'views/project_dashboard.html',
controller: 'ProjectCtrl'
})
// below does not display at all
.state('projects.one.campaigns', {
url: '/campaigns',
template: 'I cannot seem to display this text'
})
I can hit the following routes just fine: index.html/projects, index.html/projects/1, but I cannot hit this route: index.html/projects/1/campaigns
Does anyone know why I can't?
Bonus points if you can answer how I could display the projects.one.campaigns state on the same URL page as the projects.one state.
The reason is because projects.one matches before projects.one.campaigns
Add a projects.one abstract state and then add a projects.one.default state with the templateUrl.
.state('projects.one', {
url: '/{projectId:[0-9]{1,8}}',
abstract:true,
template: '<ui-view/>',
})
.state('projects.one.default', {
url: '',
templateUrl: 'views/project_dashboard.html',
controller: 'ProjectCtrl'
})
.state('projects.one.campaigns', {
url: '/campaigns',
template: 'I cannot seem to display this text'
}
To display the template of the campaigns on the same page of the projects.one you should not use a state but a directive instead and toggle with ng-show on the same page.
I just spent whole day dealing with this problem.
I found out, that you don't need abstract states at all!
Try this:
index.html:
<div class="container"><ui-view/></div>
use directive ui-view as a tag in the top level template.
Now all your nested templates wrap like this:
<ui-view>
<div>
template code
</div>
</ui-view>
and now you can just:
$stateProvider
.state('list', {
url: '',
templateUrl: 'views/project_list.html',
controller: 'ProjectListCtrl'
})
// below display properly
.state('one', {
url: '/{projectId:[0-9]{1,8}}',
templateUrl: 'views/project_dashboard.html',
controller: 'ProjectCtrl'
})
// below does not display at all
.state('one.campaigns', {
url: '/campaigns',
template: 'I cannot seem to display this text'
})
I needed general solution for the nesting and this works. Now you can create very deep nesting easily (for example one.campaing.group.member.note). If you will use ui-view on the top level and wrap all templates with the ui-view, they contact of each template will replace content of the top level ui-view (which is empty).