ui-router nested states over two levels - angularjs

I'm trying to nest states over two levels but i get the following error:
Error: Could not resolve 'purchases.inventory.create-move' from state 'purchases.inventory'
Here are the first and second level routes:
(function () {
'use strict';
angular.module( 'app.purchases' )
// Collect the ui-route states
.constant( 'states', getRouteStates() )
// Configure the ui-route states and state resolvers
.config( [ '$stateProvider', '$urlRouterProvider', 'states', stateConfigurator ] );
function stateConfigurator( $stateProvider, $urlRouterProvider, states ) {
states.forEach( function ( state ) {
$stateProvider.state( state.name, state.config );
} );
$urlRouterProvider.otherwise( "/" );
}
// Define the ui-route states
function getRouteStates() {
return [
{
name: 'purchases',
config: {
url: '/compras',
views: {
'content-body': {
templateUrl: './modules/purchases/purchases-dashboard.view.html',
controller: 'PurchasesDashboardController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Compras'
}
}
},
{
name: 'purchases.inventory',
config: {
url: '/movimientos',
views: {
'panel-body': {
templateUrl: './modules/purchases/inventory/inventory-dashboard-options.view.html',
controller: 'InventoryDashboardController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Inventario'
}
}
},
{
name: 'purchases.products',
config: {
url: '/productos',
views: {
'panel-body': {
templateUrl: './modules/purchases/products/products-dashboard-options.view.html',
controller: 'ProductsDashboardController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Productos'
}
}
},
{
name: 'purchases.suppliers',
config: {
url: '/proveedores',
views: {
'content-body': {
templateUrl: './modules/purchases/suppliers/suppliers-dashboard-options.view.html',
controller: 'SuppliersDashboardController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Proveedores'
}
}
}
];
}
})();
Here are the third level routes (These aren't working):
(function () {
'use strict';
angular.module( 'app.purchases.inventory' )
// Collect the ui-route states
.constant( 'states', getRouteStates() )
// Configure the ui-route states and state resolvers
.config( [ '$stateProvider', '$urlRouterProvider', 'states', stateConfigurator ] );
function stateConfigurator( $stateProvider, $urlRouterProvider, states ) {
states.forEach( function ( state ) {
$stateProvider.state( state.name, state.config );
} );
$urlRouterProvider.otherwise( '/' );
}
// Define the ui-route states
function getRouteStates() {
return [
{
name: 'pruchases.inventory.create-move',
config: {
url: '/nuevo-movimiento',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/create-move/create-move.view.html',
controller: 'CreateMoveController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Nuevo Movimiento'
}
}
},
{
name: 'pruchases.inventory.list-moves',
config: {
url: '/movimientos',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/read-moves/list-moves.view.html',
controller: 'ReadMovesController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Lista de Movimientos'
}
}
},
{
name: 'pruchases.inventory.detail-move',
config: {
url: '/movimientos/:move_id/:move_date',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/read-moves/detail-move.view.html',
controller: 'ReadMovesController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Detalle'
}
}
},
{
name: 'pruchases.inventory.update-move',
config: {
url: '/movimientos/:move_id/:move_date/actualizar',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/update-move/update-move.view.html',
controller: 'UpdateMoveController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Actualizacion'
}
}
}
];
}
})();
In the template what i do is:
<a ui-sref="pruchases.inventory.create-move">Create Move</a>
Is that ui-router doesn't support over two level nested routes?

I just mispelled the state name, here are the corrected states:
function getRouteStates() {
return [
{
name: 'purchases.inventory.create-move',
config: {
url: '/nuevo-movimiento',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/create-move/create-move.view.html',
controller: 'CreateMoveController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Nuevo Movimiento'
}
}
},
{
name: 'purchases.inventory.list-moves',
config: {
url: '/movimientos',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/read-moves/list-moves.view.html',
controller: 'ReadMovesController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Lista de Movimientos'
}
}
},
{
name: 'purchases.inventory.detail-move',
config: {
url: '/movimientos/:move_id/:move_date',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/read-moves/detail-move.view.html',
controller: 'ReadMovesController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Detalle'
}
}
},
{
name: 'purchases.inventory.update-move',
config: {
url: '/movimientos/:move_id/:move_date/actualizar',
views: {
'panel-body#': {
templateUrl: './modules/purchases/inventory/update-move/update-move.view.html',
controller: 'UpdateMoveController',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: 'Actualizacion'
}
}
}
];
}

Related

Angular could not resolve from state

I used jhipster to generate my app and I tried to add two different types of forms, that would both use same entity (one wouldn't use all fields in entity and other would use all).
Now, it works alright for:
.state('xyz', {
parent: 'entity',
url: '/xyz',
data: {
authorities: ['ROLE_USER'],
pageTitle: 'xyzs'
},
views: {
'content#': {
templateUrl: 'app/entities/xyz/xyzs.html',
controller: 'XyzController',
controllerAs: 'vm'
}
},
resolve: {
}
}).state('xyz.new', {
parent: 'xyz',
url: '/new',
data: {
authorities: ['ROLE_USER']
},
onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
$uibModal.open({
templateUrl: 'app/entities/xyz/xyz-dialog.html',
controller: 'XyzDialogController',
controllerAs: 'vm',
backdrop: 'static',
size: 'lg',
resolve: {
entity: function () {
return {
...
};
}
}
}).result.then(function() {
$state.go('xyz', null, { reload: true });
}, function() {
$state.go('xyz');
});
}]
})
And it works alright, but if I change it a small bit and use:
.state('xyz', {
parent: 'entity',
url: '/xyz',
data: {
authorities: ['ROLE_USER'],
pageTitle: 'xyzs'
},
views: {
'content#': {
templateUrl: 'app/entities/xyz/xyzs.html',
controller: 'XyzController',
controllerAs: 'vm'
}
},
resolve: {
}
}).state('a-xyz.new', {
parent: 'xyz',
url: '/a/new',
data: {
authorities: ['ROLE_USER']
},
onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
$uibModal.open({
templateUrl: 'app/entities/xyz/a-xyz-dialog.html',
controller: 'XyzDialogController',
controllerAs: 'vm',
backdrop: 'static',
size: 'lg',
resolve: {
entity: function () {
return {
...
};
}
}
}).result.then(function() {
$state.go('xyz', null, { reload: true });
}, function() {
$state.go('xyz');
});
}]
})
And I've change my
ui-sref="xyz.new"
to
ui-sref="a-xyz.new"
in my html template
I'm getting an error:
Error: Could not resolve 'a-xyz.new' from state 'xyz'
transitionTo#http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3180:17
go#http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3108:14
clickHook/</transition<#http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:4158:9
timeout/timeoutId<#http://localhost:9000/bower_components/angular/angular.js:19157:28
completeOutstandingRequest#http://localhost:9000/bower_components/angular/angular.js:5869:7
Browser/self.defer/timeoutId<#http://localhost:9000/bower_components/angular/angular.js:6145:7
The dot notation is basically used to indicate child state for a parent state. You may refer to this link for better understanding of nested views/states.
Nested Views
Go through this:
Why Parent State must exist
One parent can have multiple child states. So, if your parent state is 'xyz', you can multiple child states as 'xyz.a', 'xyz.b', 'xyz.c' etc.

ui-router-extras stateParams empty

can anyone help me on this
I have got a question about params:
1) when I go to app.usermanagement.user({id:40}) in router.config in resolve function $stateParams is empty. I guess I missed some option.
I'm going to that state by ui-sref="app.usermanagement.user({id:40})"
Here is code below:
var states = [];
states.push({
name: 'app',
url: '/',
deepStateRedirect: true,
resolve: {
languages: function (CommonData) {
return CommonData.getLanguages();
},
r1s: load([
'ui.select'
]).deps
},
views: {
'#': {
templateUrl: 'tpl/app.html'
}
}});
states.push({
name: 'app.usermanagement',
url: 'userManagement',
templateUrl: 'app/views/user-managment.html',
controller:'UserManagmentController',
deepStateRedirect: { default: "app.usermanagement.search" }
});
states.push({
name: 'app.usermanagement.search',
url: '/search',
templateUrl: 'app/views/tabs/user-managment/user-search.html',
controller:'UserSearchController'
});
states.push({
name: 'app.usermanagement.user',
url: '/user/{id}',
controller:'UserPageController',
templateUrl: 'app/views/tabs/user-managment/user-page.html',
resolve: {
user: function ($stateParams, UserData) {
return UserData.getUserById($stateParams.id);
}
},
deepStateRedirect: { default: "app.usermanagement.user.details" }
});
states.push({
name: 'app.usermanagement.user.details',
url: '/details',
controller:'UserDetailsController',
templateUrl: 'app/views/tabs/user-managment/user-details.html'
});
states.push({
name: 'app.usermanagement.user.friends',
url: '/friends',
templateUrl: 'app/views/tabs/user-managment/user-friends.html'
});
ok I was missing property params:true in deepStateRedirect object
deepStateRedirect: { default: "app.usermanagement.user.details", params:true }

AngularJS UI-Router default views

Here's the example code.
http://plnkr.co/edit/jXEQ9xemL1A5b9KKKcAw?p=preview
var app = angular.module('npAdmin', ['ui.router']);
app.config(['$httpProvider', '$stateProvider', '$urlRouterProvider',
function($httpProvider, $stateProvider, $urlRouterProvider) {
$stateProvider
.state('common', {
templateUrl: 'tpl.common.html',
abstract: true,
// views: {
// 'footer': {
// templateUrl: 'footer.html'
// }
// }
})
.state('common.dashboard', {
url: '/dashboard',
views: {
'content': {
template: '<div><h4>dashboard</h4></div>'
},
'footer': {
templateUrl: 'footer.html'
}
}
})
.state('common.crm', {
url: '/crm',
views: {
'content': {
template: '<div><h4>CRM</h4></div>'
},
'footer': {
templateUrl: 'footer.html'
}
}
})
.state('common.abc', {
url: '/abc',
views: {
'content': {
template: '<div><h4>ABC</h4></div>'
},
'footer': {
templateUrl: 'newfooter.html'
}
}
})
.state('landing', {
templateUrl: 'tpl.login.html',
abstract: true,
})
.state('landing.login', {
url: '/login',
template: '<div><h4>Wow</h4></div>',
});
$urlRouterProvider.otherwise('/crm');
}
]);
The default 'templateUrl' of 'footer' is 'footer.html', but it's 'newfooter.html' for some state.
Is there a good way to set default footer in this case?
I tried to use 'templateUrl' and 'views' at the same time, but it doesn't work.
There is updated plunker. We can use absolute naming in the parent 'common':
.state('common', {
abstract: true,
views: {
'': {
templateUrl: 'tpl.common.html',
},
'footer#common': {
templateUrl: 'footer.html'
}
}
})
And override it only if needed ('dashboard' and 'crm' will use the parent footer, while the 'abc' is defining an override - special one: newfooter.html)
.state('common.dashboard', {
url: '/dashboard',
views: {
'content': {
template: '<div><h4>dashboard</h4></div>'
},
// provided by parent
//'footer': {
// templateUrl: 'footer.html'
//}
}
})
.state('common.crm', {
url: '/crm',
views: {
'content': {
template: '<div><h4>CRM</h4></div>'
},
// provided by parent
//'footer': {
// templateUrl: 'footer.html'
//}
}
})
.state('common.abc', {
url: '/abc',
views: {
'content': {
template: '<div><h4>ABC</h4></div>'
},
'footer': {
templateUrl: 'newfooter.html'
}
}
Check it here
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})

Angular UI Router multiple/named routes

I have a user layout file that is the template for any user pages:
<div class="user-wrapper">
<div ui-view="menu"></div>
<div ui-view="content"></div>
</div>
Depending on the state I want the menu to be different. Such as:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/one.html" }
},
});
.state('user.two', {
url: '/two',
controller: 'twoController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/two.html" }
},
});
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
},
});
Now you can see "one" and "two" both use the same menu but "three" uses a different menu. This all works fine but is there a way to avoid duplicating the menu on "one" and "two".
Such as making a "user.client" state that uses the "user-menu.html" then "one" would be "user.client.one" instead and only have to specify the content.
I think the main problem is the
<div ui-view="content"></div>
is on the grandfather of the "user.client.one" so how can it specify the content?
I would say, that the trick is to move the "menu" view definition into parent state "user"
.state('user', {
url: '/user',
views: {
"" : {
templateUrl: 'partials/user.html',
controller: 'userController',
},
"menu#user": { templateUrl: "partials/client-menu.html" },
},
...
So, what happened? any child state of the "user" will already have the content of the "menu" filled, with the default templateUrl: "partials/client-menu.html"
Any other child, can override that...
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
// "menu": already set by parent
"content": { templateUrl: "partials/one.html" }
....
.state('user.two', {
url: '/two',
views: {
// "menu": set in parent
"content": { templateUrl: "partials/two.html" }
...
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
// here we override that
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
...
Maybe, check this Q & A for some more ideas about multi view nesting:
multiple ui-view html files in ui-router
AngularJS ui-router view structure product site
I think a found a solution user the # for absolute views:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.client', {
url: '/client',
views: {
"menu": { templateUrl: "partials/client-menu.html" }
},
})
.state('user.admin', {
url: '/admin',
views: {
"menu": { templateUrl: "partials/admin-menu.html" }
},
})
.state('user.client.one', {
url: '/one',
controller: 'oneController',
views: {
"content#user": { templateUrl: "partials/one.html" }
},
});
.state('user.client.two', {
url: '/two',
controller: 'twoController',
views: {
"content#user": { templateUrl: "partials/two.html" }
},
});
.state('user.admin.three', {
url: '/three',
controller: 'threeController',
views: {
"content#user": { templateUrl: "partials/three.html" }
},
});
It feels abit cleaner but I'm not sure if its the right approach still.

AngularJS ui-router navigate to url

I'd like to navigate to the following url through the browser:
http://localhost:9001/jira.
This only works if I add a hash to the url, like this:
http://localhost:9001/#/jira.
I tried setting the html5Mode to true, but this only removes the hash from the url. It still does not allow me to navigate directly to the url.
Here is my code:
grey.config( function( $stateProvider, $provide, $locationProvider ) {
$locationProvider.html5Mode( true ).requireBase( false );
// Set up the different views
$stateProvider
.state('index', {
url: '',
views: {
'jira_filters': {
templateUrl: 'app/partials/jira_filters.html'
},
'ciq_filters': {
templateUrl: 'app/partials/ciq_filters.html'
},
'priority': {
templateUrl: 'app/partials/priority.html'
},
'status': {
templateUrl: 'app/partials/status.html'
},
'rca': {
templateUrl: 'app/partials/rca.html'
},
}
})
.state('jira', {
url: '/jira',
views: {
'jira_filters': {
templateUrl: 'app/partials/jira_filters.html'
},
'ciq_filters': {
templateUrl: 'app/partials/ciq_filters.html'
},
'priority': {
templateUrl: 'app/partials/priority.html'
},
'status': {
templateUrl: 'app/partials/status.html'
},
'rca': {
templateUrl: 'app/partials/rca.html'
},
}
});
});

Resources