I have some two ui-router states in my angular application, which works fine, like this:
app.config(["$stateProvider",
function($stateProvider){
$stateProvider
.state("settings", {
url: "/settings",
views: {
"secondMenu": {
templateUrl: "second_menu.html?parent=settings",
controller: "settingsController"
},
"thirdMenu": {
template: empty_template
}
}
})
.state("cabinet", {
url: "/cabinet",
views: {
"secondMenu": {
templateUrl: "second_menu.html?parent=cabinet",
controller: "cabinetController"
},
"thirdMenu": {
template: empty_template
}
}
})
But only part of my menu i need work with angular. Other part of menu must go to static (not angular) url of my site, like this:
<ul>
<li>static-url</li>
<li><a ui-sref="cabinet">cabinet angular url</a></li>
<li><a ui-sref="settings">settings angular</a></li>
</ul>
And when i click on angular-urls - i get need information in my ng-view , but if after then i click on static-url - my url changing from /#/cabinet (for ex.) to /static-url/, but query to server does not exist. Page content saving as in cabinet angular url.
How I can disabling angular ui-router working on /static-url/ ?
So for future lurkers, here's what you need to do. Just add this attribute to your static page's anchor tag:
target="_self"
Like this:
<ul>
<li>static-url</li>
<li><a ui-sref="cabinet">cabinet angular url</a></li>
<li><a ui-sref="settings">settings angular</a></li>
</ul>
Related
I'm using angular ui router and routing my pages, here my main page is contracts.html
I want to route to another page from this page hence I have written the following code. But it is not working, please take a look at the following code :
<li role="menuitem"><a ui-sref=".monthlysettings" onclick="$('#simple-btn-keyboard-nav2').text('PDC Settings')">PDC Settings</a></li>
.state('contracts', {
url: '/contracts',
controller: 'contractsController',
templateUrl: 'contracts.html'
}).state('contracts.monthlysettings', {
url: '/monthlysettings',
controller: 'monthlysettingsController',
templateUrl: 'monthlysettings.html'
})
Your state name should be the full name contracts.monthlysettings
<li role="menuitem"><a ui-sref="contracts.monthlysettings" onclick="$('#simple-btn-keyboard-nav2').text('PDC Settings')">PDC Settings</a></li>
I have my routing defined as below
$stateProvider
('MasterPage', {
url: '/',
templateUrl: 'views/master.html',
})
.state('MasterPage.dashboard', {
url: 'dashboard',
templateUrl: 'views/dash.html',
})
.state('MasterPage.test', {
url: 'test/:id',
templateUrl: 'views/test.html',
})
$urlRouterProvider.otherwise('/');
I have links that allows me to navigate from mainpage to dashboard and then to the test page which works fine. When I navigate to the test page with an id:1234, which makes my url as <HOST>/#/test/1234, and try to refresh it fails. It gives me an error saying:
Cannot resolve state 'MasterPage.test/1234' from 'MasterPage.test'
Why is UI-Router considering the url segment as a state?
Update
I dont have any ui-sref. I am going to the test page by using $state.go('MasterPage.test', {id:1234}).
There is working plunker
This issue is usually related to wrong ui-sref setting
<a ui-sref="MasterPage.test/1234">
we need to split and pass 1) the state name, and 2) state params like this:
<a ui-sref="MasterPage.test({id:1234})">
In case, we want to use href, we just have to concatenate parent and child url definitions (parent '/', child 'test/:id') :
<a href="/test/1234">
EXTEND
So, these states (almost unchanged):
.state('MasterPage', {
url: '/',
templateUrl: 'views/master.html',
})
.state('MasterPage.dashboard', {
url: 'dashboard',
templateUrl: 'views/dash.html',
})
.state('MasterPage.test', {
url: 'test/:id',
templateUrl: 'views/test.html',
})
will work with these links
<a href="#/">
<a href="#/dashboard">
<a href="#/test/1234">
<a href="#/test/9875">
<a ui-sref="MasterPage">
<a ui-sref="MasterPage.dashboard">
<a ui-sref="MasterPage.test({id:2222})">
<a ui-sref="MasterPage.test({id:4444})">
There is working plunker
I created a tabbed edit form like this:
<ul class="nav nav-tabs">
<li role="presentation" ui-sref-active="active">
<a ui-sref="products.edit.general">General</a>
</li>
... more tabs ...
</ul>
My routes look like:
$stateProvider
.state('products.edit', {
abstract: true,
url: '/{product_id:int}/edit',
templateUrl: 'partials/products.edit.html',
controller: 'ProductsEditController'
})
.state('products.edit.general', {
url: '',
templateUrl: 'partials/products.edit.general.html'
})
I have several files like partials/products.edit.general.html for each tab. each of them contains different form fields.
Now, I'm looking to extend this code to create products using the same form fields and just switching between POST/PUT on the controller. To do so, I created the products.new set of routes, but I'm failing to implement them on the HTML above. Or should I set up my .new rules differently?
You can pass data or promises to the controller from the .state configuration as follows
.state('products.edit', {
abstract: true,
url: '/{product_id:int}/edit',
templateUrl: 'partials/products.edit.html',
controller: 'ProductsEditController',
resolve: {
action: function () {
return 'edit';
}
}
});
This will resolve as a dependency (or dependencies if multiple properties used in resolve) of the controller:
angular.module('myApp').controller(function( action, /*other dependencies...*/){
if(action === 'edit'){
// editing specific code or variables
}else{
// create specific code
}
});
See UI Router docs for more details
I'm a newb and have to be doing something stupid here, and I can't figure it out for the life of me. Thanks in advance for any help!
In short, I have 3 pages that all load correctly when visiting them directly through the address bar in a browser:
#/communities
#/companies
#/companies/:id
I have used ui-router to define the company states as follows:
//companies.js file:
.config(function config( $stateProvider ) {
$stateProvider
.state( 'companies', {
url: '/companies',
views: {
"main": {
templateUrl: 'companies/companies.tpl.html'
}
},
data:{ pageTitle: '' }
});
})
//companies.detail.js file:
.config(function config( $stateProvider ) {
$stateProvider
.state( 'companies.detail', {
url: '/:id',
views: {
//use # to force use of parent ui-view tag
"main#": {
templateUrl: 'companies/companies.detail/companies.detail.tpl.html'
}
},
data:{ pageTitle: '' }
});
})
.controller('CompanyDetailCtrl', ['CompaniesService', '$stateParams',
function(CompaniesService, $stateParams) {
alert($stateParams.id); //this fires when I navigate to page briefly
var _this = this; //need to get better approach for this (ideally remove)
_this.hoas = [];
CompaniesService.getCompanyHoas($stateParams.id).then(function(response) {
_this.hoas = response;
});
}])
;
//communities.tpl.html calling page snippet:
<a ui-sref="companies.detail({id:hoa.company.id})">{{hoa.company.name}}</a>
The URL is created correctly when I hover over in a browser (ie: "companies/223") AND the companies/223 page is correctly navigated to BUT only for a split second and then redirects back to the calling page. The page IS caught in browser history (so I can go back to it and stay on it and it works perfectly), but when I click this link it always redirects back.
What am I missing??? It's killing me. Thanks for your help. :)
The reason the state was always redirecting back to the calling page is because I had teh ui-sref wrapped in a parent ui-sref element that was pointing back to the calling page:
<a ui-sref="companies" class="list-group-item"
ng-click="list.selectCommunity(community)"
ng-switch on="list.isSelected(community)"
ng-class="{'active': list.isSelected(community)}" >
<div ng-switch-when="true">
<div class="table-responsive">
<table class="table">
...
<td class="hidden-xs"><a ui-sref="companies.detail({id:hoa.company.id})">{{hoa.company.name}}</a></td>
...
</table>
</div>
</div>
</a>
I easily corrected this by changing the first line to:
<a href="#" class="list-group-item" ...
Hope this helps someone in the future. I just wish I didn't assume the problem was within my JS!
In my project many organizations. Each organization page contains two parts: header with some organization info, which must load only once, and tabs zone. For tabs i use nested states.
Now question: Can i walk by tabs without reloading organizationCtrl?
router.js
$stateProvider
.state('organization', {
url: '/organisations/:id',
templateUrl: 'organization/show.html',
controller: 'organizationCtrl'
})
.state('organization.bio', {
url: '/bio',
templateUrl: 'organization/bio.html',
controller: 'organizationBioCtrl'
})
.state('organization.bio', {
url: '/gallery',
templateUrl: 'organization/gallery.html',
controller: 'organizationGalleryCtrl'
});
organization/show.html
<ul>
<li ui-sref-active="selected">
<a ui-sref="organization.bio({ id: organization.id })">Bio</a>
</li>
<li ui-sref-active="selected">
<a ui-sref="organization.gallery({ id: organization.id })">Gallery</a>
</li>
</ul>
The state change is triggered even if some state-Param is changed. Therefore, until our user will navigate between bio and gallery of the same organisation {id} - the organizationCtrl won't be reloaded. In the moment when user will navigate to different organisation {id} ... new state change will be triggered and new organiaztionCtrl will be put in play.
But we can solve it. Here is a working plunker
We will split the organisation state into 2 (parent/child). One will be a base/root of the organisation without the dependency upon concrete organisation {id}. And that means - will be instantiated only once...
.state('base', {
abstract : true,
template: '<div ui-view=""></div>',
controller: 'baseCtrl'
})
.state('organization', {
parent : 'base',
url: '/organisations/:id',
controller: 'organizationCtrl'
...
})
.state('organization.bio', {
url: '/bio',
...
})
.state('organization.gallery', {
url: '/gallery',
...
});
And now navigating among these links:
<ul>
<li><a ui-sref="organization.bio( { id: 1 })">Orga1 - Bio</a></li>
<li><a ui-sref="organization.gallery({ id: 1 })">Orga1 - Gallery</a></li>
<li><a ui-sref="organization.bio( { id: 2 })">Orga2 - Bio</a></li>
<li><a ui-sref="organization.gallery({ id: 2 })">Orga2 - Gallery</a></li>
</ul>
will not resinstantiate the baseCtrl even if the {id} will be changed.
.controller('baseCtrl', function($scope,...) {
// pretty stable one
})
.controller('organizationCtrl', function($scope, ...) {
// changing with id change
})
Because the base state is abstract, it won't introduce anything into our current model, we only gain the baseCtrl...
Please, observe described behaviour in this working plunker