ui router - abstract state inside à normal one (3 levels) - angularjs

i'm trying to get work this combination of sub levels routes.
http://plnkr.co/edit/1nBzppJkB45Ljv5SRW4b?p=preview
i took a sample from ui-route on github and added a parent view (contactg).
$stateProvider
.state('contactg', {
url: '/contactg',
templateUrl: 'contactG.html',
onEnter: function () { console.log("enter contactG"); }
})
.state('contactg.contacts', {
abstract: true,
url: '/contacts',
templateUrl: 'contacts.html',
controller: function ($scope) {
$scope.contacts = [{ id: 0, name: "Alice" }, { id: 1, name: "Bob" }];
},
onEnter: function () {
console.log("enter contacts");
}
})
.state('contactg.contacts.list', {
url: '/list',
// loaded into ui-view of parent's template
templateUrl: 'contacts.list.html',
onEnter: function () {
console.log("enter contacts.list");
}
})
.state('contactg.contacts.detail', {
url: '/:id',
// loaded into ui-view of parent's template
templateUrl: 'contacts.detail.html',
controller: function ($scope, $stateParams) {
$scope.person = $scope.contacts[$stateParams.id];
},
onEnter: function () {
console.log("enter contacts.detail");
}
})
My issues is when i click on an item in contactg.contacts.list, the link generated tends to redirect me to /contacts/:id (detail) instead of /contactg/contacts/:id
is there a way to specify that ?
Thanks
Guillaume.

Related

How do I get URL parameters on AngularJS SPA when using stateProvider for routing

For example, on the last state on the below code I want to get the value of "category" URL parameter so that I can use it to retrieve some from the database
var app = angular.module("myApp",["ui.router"]);
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/");
$stateProvider
.state("main", {
url: "/",
views: {
"slider": {
templateUrl: "slider.html"
},
"departments": {
templateUrl: "departments.html"
},
"brands": {
templateUrl: "brands.html"
}
}
})
.state("cart", {
url: "/cart",
views: {
"cart": {
templateUrl: "../account/cart.php"
}
}
})
.state("department", {
url: "/department/:category",
views: {
"department": {
templateUrl: "department.php"
}
}
});
});
Create a controller, pass stateParams and instantiate the controller within the views of the last state
.state("department", {
url: "/department/:category",
views: {
"department": {
templateUrl: "department.php",
controller: "myController"
}
}
});
});
app.controller('myController', function($stateParams) {
var param = $stateParams.category;
document.getElementById("category").value = param;
});

AngularJS uiRouter access controller from other view

I have simple hierarchical state:
angular
.module('App.Module.Suppliers', [])
.config(function($stateProvider) {
return $stateProvider
.state('suppliers', {
url: '/suppliers',
views: {
main: {
templateUrl: 'views/layouts/wrapper.html'
}
}
})
.state('suppliers.edit', {
url: '/:id',
views: {
entity_view: {
templateUrl: 'views/layouts/foo.html'
}
}
})
.state('suppliers.edit.details', {
url: '/edit',
views: {
entity_sub_view: {
controller: function () {
this.foo = {bar: "TEST HEADER"};
},
controllerAs: 'vm',
templateUrl: 'views/layouts/main.html'
}
}
});
});
main and entity_view views are generic for all entities and only entity_sub_view changes with core information.
Now in entity_view I want to use some value like <h2>{{vm.foo.bar}}</h2> but it seems that I can't access vm inside these parent states.
Is there a way to pass this and other parameters to parent states to use?
So I found solution that fits my need. Basically you can set controllerAs to top-most state and access it via $scope:
angular
.module('App.Module.Suppliers', [])
.config(function($stateProvider) {
return $stateProvider
.state('suppliers', {
url: '/suppliers',
views: {
main: {
templateUrl: 'views/layouts/wrapper.html'
controller: function () {
this.foo = null;
}
controllerAs: 'mainCtrl'
}
}
})
.state('suppliers.edit', {
url: '/:id',
views: {
entity_view: {
templateUrl: 'views/layouts/foo.html'
}
}
})
.state('suppliers.edit.details', {
url: '/edit',
views: {
entity_sub_view: {
controller: function () {
this.foo = {bar: "TEST HEADER"};
},
controllerAs: 'vm',
templateUrl: 'views/layouts/main.html'
}
}
});
});
And in some controller do
this.$scope.mainCtrl.foo = {bar: "TEST HEADER"};
In view
{{mainCtrl.foo.bar}}

How to modify url of a state in AngularJS ui-routes

I am on angular 1.6. Trying to override value of a ui-router state.
Initial states as follows :
$stateProvider.state('parent', {
abstract: true,
parent: 'ancestor',
url: '/parent',
data: {
authorities: [A,B]
},
views: {
'content#': {
templateUrl: 'app/scripts/myapp/module/parent.html'
}
}
})
.state('child', {
parent: 'parent',
abstract: true,
views: {
'tabs': {
templateUrl: 'app/scripts/myapp/module/submodule/child.html',
controller: 'ChildController',
controllerAs: 'childController'
}
}
})
.state('grandChild', {
parent: 'child',
url: '/{dataSource:(?:option1|option2|option3)}',
views: {
'body': {
templateUrl: 'app/scripts/myapp/module/submodule/grandchild.html',
controller: 'GrandChildController',
controllerAs: 'grandChildController'
},
},
resolve: {
groups: ['MyService', '$transition$', function (MyService, $transition$) {
var selectedSource = $transition$.params().dataSource ? $transition$.params().dataSource : 'option1';
return MyService.getGroups(selectedSource);
}]
}
})
Then in one of sub-implementation I am trying to override value of url - adding option4 for one of the state.
var states = $stateRegistry.deregister('grandChild');
$stateRegistry.register(states[0]);//There is one more child. For simplicity not showing here.
states[1].url.pattern = '/{dataSource:(?:option1|option2|option3|option4)}';
$stateRegistry.register(states[1]);
when I do following on 'grandChild'
$state.go('grandChild', {dataSource: 'option4'});
I get error as
Param values not valid for state 'grandChild'. Invalid params: [ dataSource ]
when I inspect $state
I see something weird.
$state.$current.params.datasource.type.pattern = /(?:option1|option2|option3)/
$state.$current.url.pattern = "/{dataSource:(?:option1|option2|option3|option4)}"
$state.$current.url._compiled[0] = /((?:option1|option2|option3))/

Passing resolved data to child state in Ui-Router

So, I have a state where the resolve spits out an array which shows correctly on the frontend.
But I can't seem to be able to pass the parent resolve data to the child state.
$stateProvider.state('berliner', {
url: '/berlinerliste',
params : {search: 'Berliner 2017'},
resolve: {
fair: function(SearchService, $stateParams) {
return SearchService.getAllExhibitors($stateParams.search);
}
},
views: {
'header': {
templateUrl: 'header.htm'
},
'main':{
templateUrl: 'bl2017.htm',
controller: function($scope, fair){
$scope.fair = fair;
console.log($scope.fair);
}
}
}
})
.state('berliner.exhibitor', {
url: '/{id}',
resolve: {
exhibitor: function($stateParams, fair) {
var slug = $stateParams.id;
return slug;
}
},
views: {
'header': {
templateUrl: 'header.htm'
},
'wop':{
templateUrl: 'exhibitor.htm',
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
}
}
})
All the console log come out undefined.
What am I missing?
PLUNKR
Here's a Plunkr to examplify the issue.
I would say, that the concept should work.. just:
controller belongs to view. not to all views: {}
E.g. this (wrong)
// each view can have controller,
// but views : {} property 'controller' is not used at all
views: {
'header': {
templateUrl: 'header.htm'
},
'wop':{
templateUrl: 'exhibitor.htm',
},
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
should be adjusted as that:
views: {
'header': {
templateUrl: 'header.htm'
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
},
'wop':{
templateUrl: 'exhibitor.htm',
controller: ...
There is an example, how
parent does resolve
child view's controller consumes it
states:
.state('parent', {
url: "/parent",
templateUrl: 'tpl.html',
resolve: {
example: ['$timeout', function($timeout){
return $timeout(function(){
return {x: 1}
},100)
}],
},
})
.state('parent.child', {
url: "/child",
templateUrl: 'tpl.html',
controller: 'ChildCtrl',
})
child controller
.controller('ChildCtrl', ['$scope', 'example', function ($scope, example) {
console.log(JSON.stringify(example));
}])
Check it here

UI Router Child States in Angular not Loading Controllers

I am having an issue loading controllers / templates for each child state. I have a console.log in each state controller, yet they don't fire. Any ideas will be greatly appreciated!
Intent is to always load artist for every child state following.
var stateConfig = ['$stateProvider', function($stateProvider) {
// State Configurations
$stateProvider
.state('artist', {
abstract: true,
url: '/' + artistSlug,
controller: "artistCtrl",
resolve: {
artist: function(artist){
return artist.getArtist();
}
}
})
.state('events', {
parent: 'artist',
url: '',
controller: 'eventsCtrl',
templateUrl: "/templates/artist/events.html"
})
I think you need to revise your states / params
It should go artists -> artists.artist -> artists.artist.events. Then if you go to //site.com/artists/justintimberlake/events it will resolve artist and then events
var stateConfig = ['$stateProvider', function($stateProvider) {
// State Configurations
$stateProvider
.state('artists', {
abstract: true,
url: '/artists'
})
.state('artists.artist', {
url: '/:artistId',
controller: 'artistCtrl',
template: '<div ui-view>Artist Template Wrapper for Artist and Events</div>',
resolve: {
artist: function (artist, $stateParams) {
return artist.getArtist($stateParams.artistId);
}
}
})
.state('artists.artist.events', {
url: '/events',
controller: 'eventsCtrl',
templateUrl: '/templates/artist/events.html',
resolve: {
events: function (artist, $stateParams) {
return artist.getArtistEvents($stateParams.artistId);
}
}
})
}];

Resources