I have been struggling for sometime for following scenario to work right.
I am using ui-router with angularjs and I need something like:
Parent state : .state('parent', { url: '/parent/:someUserId' }
Child state as : .state('parent.child', { url: '/child' }
My requirement is child state should take route such as 'parent/:someUserId/child'
How would I be able to achieve this?
It should be simple as this:
state('parent', {
url: "/parent/:someUserId",
templateUrl: "parent.html"
}).
state('parent.child', {
url: "/todo",
templateUrl: "parent/child.html"
}).
reference: https://github.com/angular-ui/ui-router
Related
My oversimplified app.config() has:
$stateProvider.
state("/", {
url: "/",
templateUrl: "main.html"
}).
state("/newCategories", {
url: "/categories/new",
templateUrl: "/views/new_categories.html",
controller: "newCategoriesCtrl"
}).
state("/categoryPages", {
url: "/categories/:address",
templateUrl: "/views/categories.html",
controller: "categoriesCtrl",
resolve: {
categoriesDataResolve: function resolveTemplate($stateParams, DataResolver) {
return DataResolver.resolveTemplates($stateParams.address);
}
}
});
With this I can use ui-serf link with "/newCategories" to load its url: "/categories/new"
<a ui-sref="/newCategories">New Category</a>
However, when I refresh, it thinks that "/new" is part of $stateParams. Therefore it uses a different controller and tries to resolve its template (which is missing, so it gives an error).
For now I fixed it by changing the url from "/categories/new" to "/categories-new" so it won't get confused on refresh. But how do I solve this issue differently? (Maybe ui-router has a some way of dealing with it)
If I understand you right, you want to call different controller a.e. newCategoriesCtrl when user calls /categories/:address where address param is new
Changing /categories/new to "/categories-new is a right way to solve it.
Small tip: its not good practice to use / as prefix for state name. It confuses the developer and can be mixed with original URL.
$stateProvider.
//...
state("newCategories", {
url: "/categories-new",
templateUrl: "/views/new_categories.html",
controller: "newCategoriesCtrl"
}).
state("categoryPages", {
url: "/categories/:address",
templateUrl: "/views/categories.html",
controller: "categoriesCtrl",
resolve: {
//...
}
});
This is the configuration i'm using for my ui-router:
.state('parent', {
url: '/child1'
controller: ParentController,
abstract: true
})
.state('parent.child1', {
url: ''
})
.state('parent.child2', {
url: '/child2'
})
What I want to acheive ?
I want a /child1 url that I wanted to be default so I made the parent as abstract with child state url as 'empty'.
So I want that when user visits child2 state, the parent url gets replaced rather than appending it. How can i achieve that ?
If I understand you right, (please correct me if I'm wrong) you are looking to setup a routing service to achieve the following routes:
/, /child1 and /child2 and you want all states to be bound with ParentController
If that is correct you can achieve this with the following:
.state('parent', {
url: '/',
controller: ParentController,
})
.state('parent.child1', {
url: '^/child1'
})
.state('parent.child2', {
url: '^/child2'
})
For example if we were running https://localhost:3000 we could navigate as such:
parent or / would give us https://localhost:3000/
parent.child1 or /child1 would give us https://localhost:3000/child1
parent.child2 or /child2 would give us https://localhost:3000/child2
The ParentController would be invoked by all states.
I'm trying to create a structure for creating, reading, updating and destroying that consists on indenting params:
/items/create
/items/1/view || /items/1/edit || /items/1/remove
The states for those are like this in $stateProvider:
.state('items.create', {
url: '/create',
templateUrl: 'item/create.html'
})
.state('items.item', {
abstract: true,
url: '/:_id',
templateUrl: 'item/itembody.html'
})
.state('items.item.view', {
url: '/view',
templateUrl: 'item/item.html'
})
.state('items.item.edit', [... and so on ...]
I'm also redirecting /1 to /1/view using $urlRouterProvider:
.when('/items/:_id', '/items/:_id/view');
Problem is when trying to reach /items/create I'm being redirected to /items/create/view. Is there a way to protect or make an exception to this word so I can reach its URL?
I think your problem is that the urls are being combined, like so:
Appended Routes (default)
When using url routing together with nested states the default behavior is for child states to append their url to the urls of each of its parent states.
$stateProvider
.state('contacts', {
url: '/contacts',
...
})
.state('contacts.list', {
url: '/list',
...
});
So the routes would become:
'contacts' state matches "/contacts"
'contacts.list' state matches "/contacts/list". The urls were combined.
Try using different state names.
This is a syntax error, change this url: '/item/:_id.view' for this url: '/item/:_id'.
My route definition is:
$stateProvider.state("passages", {
abstract: true,
url: "/passages",
controller: "PassageController",
template: "<div ui-view></div>"
}).state("passages.list", {
url: "/list",
templateUrl: "/views/passages/list.html"
}).state("passages.upsert", {
url: "/upsert/:passageId",
templateUrl: "/views/passages/upsert.html"
});
And in my PassageController, I have console.log $stateParams.passageId, and it goes to undefined. The URL I hit is http://localhost:3000/passages/upsert/myId
it's only possible to read $stateParams property in state where it is defined.
i could be wrong but your child states don't extend the url of the parent state. the abstract parent state url is simply a default which a child will inherit if no url is defined for a child.
try defining the urls in your child states as ...
url: "/passages/list"
AND
url: "/passages/upsert/:passageId"
In my angular app, using UI-Router, have a parent state(page) that has some header information and then a navlist populated with the child routes of this parent.
It's working great, but it starts without any children active.
I'd like to activate the first child state when a user goes to the unadorned parent state (I have no way to know which child id will be the first one, although I could fetch that in the parent Controller)
Consider this code:
$stateProvider
.state('parent', {
url: '/parent',
templateUrl: 'app/parent/parent.html',
controller: 'ParentController',
controllerAs: 'prnt'
})
.state('parent.child', {
url: '/parrent/{childId}',
templateUrl: 'app/parent/childlist.html',
controller: 'ChildController',
controllerAs: 'chld'
});
Thanks in advance for the help.
Well, it is really hard to say how to redirect to first child state with childId if you know that:
...I have no way to know which child id will be the first one...
But this is the way I like the most:
Redirect a state to default substate with UI-Router in AngularJS
where we hook on an listener to state change:
app.run(['$rootScope', '$state', function($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(evt, to, params) {
if (to.redirectTo) {
evt.preventDefault();
$state.go(to.redirectTo, params)
}
});
}]);
and then we can decorate state with such setting:
$stateProvider
.state('parent', {
url: '/parent',
...
redirectTo: 'parent.child',
})
and now we can even by declare default id on that child state
.state('parent.child', {
url: '/parrent/{childId}',
params: { childId: 1},
...
where the params: { childId: 1}, is the best way I can imagine to assign default id, because:
it could be different for any combination parent/child
it is child state who should now what should be its default id (not the listener)
Read more about the params : {} here:
Angular ui router passing data between states without URL