Once my child state controller gets instantiated it does not reload again on $state.go
my router layout
.state('hotelsearch', {
url: '/search',
abstract: true,
views:{
'': {
templateUrl: "app/components/layout/layout.html"
},
"header#hotelsearch": {
templateUrl: "app/components/search/search.html"
},
"footer#hotelsearch": {
templateUrl: "app/components/footer/footer.html"
}
}
})
.state('hotelsearch.hotel', {
url: '',
views:{
'':{templateUrl: 'app/components/search/searchHotel.html'},
}
})
.state('hotelsearch.hotel.main', {
url: '',
views:{
"main#hotelsearch": {
templateUrl: 'app/components/hotel/hotelSearch.html',
controller:"hotelResult"
},
},
})
.state('hotelsearch.flight', {
url: '',
templateUrl: 'app/components/search/searchFlight.html',
})
layout
<div ui-view="header"></div>
<div ui-view="main"></div>
<div ui-view="footer"></div>
state called on successfully resolving promise
.then(function(response){
console.log(response.data.message);
if(response.data.message==="Success"){
$state.go('hotelsearch.hotel.main');
}
controller hotelResult
function hotelResult(dataservice,$scope,$stateParams){
console.log($stateParams);
dataservice.makeRequestForHotel()
.then(function(response){
console.log(response);
$scope.data=response.data.HotelGroup[0].City;
});
}
i know the controller is not reloading a second time because console.not working.
What i have tried:
1.using resolve.
2.reload:true in `$state.go`
(this causes the entire view controllers to be reloaded, as a result i get the data but the data in the suggestion box of search controller is lost)
what i am looking for is only selective reloading of the an individual state child controller
Related
I have an app that uses angular-ui-router with html5mode(true). Everything seems to work fine when running and routing to other states. following are the states.
$urlRouterProvider.otherwise("/navigation-master");
$stateProvider
.state('master', {
url: "",
views: {
"#": {
templateUrl: "content-master"
},
"nav-view": {
templateUrl: "nav-content"
}
}
})
.state('master.content', {
url: "/content/:pageId",
views: {
"content-view": {
templateUrl: function ($stateParams) {
return 'content?pageId=' + $stateParams.pageId;
}
}
},
params: {extra: null}
});
secApp.run(function ($transitions, $http, $templateCache ) {});
when i refresh the page while i'm currently in other routes(lets say master.content) it takes me back to navigation-master.
Maybe try to set the url at / and not `` in your first state
i am working on web app that uses ui-router version 0.3.2 and angular 1.5. i am having an issue with back button, when i hit the back button the url updates to appropriate state url, but does not reloads / renders the page. The controller of the new state (updated url) does not get executed. Following is my state config
$stateProvider
.state('home', {
url: '/',
reloadOnSearch: false,
templateUrl: 'homePage.html',
controller:'homeController'
})
.state('home.overView', {
url:'overView',
reloadOnSearch: false,
views: {
ovSB: {
templateUrl: 'searchParameterBarTemplate.html',
controller: 'searchParameterBarController'
}
}
})
.state('home.overView.result', {
url:'/:docType?abc&xyz&type&user&temp1&temp2',
abstract: true,
reloadOnSearch: false,
templateUrl: 'resultViewTemplate.html',
controller : 'resultPanelController'
})
.state('home.overView.result.dashboard', {
url:'',
reloadOnSearch: false,
views: {
'chart': {
templateUrl: 'chart-template.html',
controller: 'chart-Controller'
},
'oVGrid': {
templateUrl: 'ov-grid-template.html',
controller: 'ov-grid-controller'
},
'filterGrid': {
templateUrl: 'filter-stats-template.html',
controller: 'filter-stats-controller'
}
}
})
.state('home.delta',{
reloadOnSearch: false,
url:'Delta',
views:{
pcSB:{
templateUrl: 'search-parameterbar-delta-template.html',
controller : 'search-parameterBar-delta-controller'
}
}
})
.state('home.delta.result',{
url:'/:docType?xyz_1&abc_1&xyz_2&abc_2',
reloadOnSearch: false,
templateUrl: 'delta-template.html',
controller : 'delta-controller'
})
.state('home.details', {
url: 'details',
views: {
detailsSB: {
templateUrl: 'search-paramBar-details-template.html',
controller: 'search-paramBar-details-controller'
}
}
})
.state('home.details.result', {
url: '/:documentType?abc&xyz&user&temp1&temp2',
abstract: true,
templateUrl: 'details-view-template.html',
controller: 'details-view-controller'
})
.state('home.details.result.dashboard',{
url:'',
views:{
perGraph : {
controller :'per-graph-controller',
templateUrl: 'per-graph-template.html'
},
detailsGrid: {
controller: 'details-grid-controller',
templateUrl: 'details-grid-controller-template.html'
}
}
});
So for example if i navigate from home.overview.result.dashboard (url -> localhost:12345/overview/doctype?abc&xyz&user&temp1&temp2) state to home.details.result.dashboard state with url localhost:12345/details/doctype?abc&xyz&user&temp1&temp2 and hit backbutton, the url updates to localhost:12345/overview/doctype?abc&xyz&user&temp1&temp2 however it does not reloads/renders the page.
I believe I can you use this solution and trigger the reload, but I am looking for a better solution than this which adheres to ui router. is there something i am missing with state config / doing wrong? Any help pertaining to this would be highly appreciated.
Thank you
it will be firing $stateChangeStart event. use location directive to rout it . please refer the below snippet
$rootScope.$on('$routeChangeStart', function (event,next) {
$location.path(next.$$route.originalPath);
});
this can resolve your problem. but its not the perfect solution
I'm trying to define states in a 3 columns layout with the left column having the same content. But at this time, I had to repeat the templateUrl for all direct nested states.
.state('workspace', {
url: '/',
templateUrl: 'app/workspace/workspace.view.html'
})
.state('workspace.images', {
url: 'images',
views: {
'sidebar': {
templateUrl: 'app/workspace/sidebar.view.html',
controller : 'Workspace.SidebarController as vm'
},
'content': {
templateUrl: 'app/workspace/imageslist.view.html',
controller : 'Workspace.ImagesListController as vm'
}
}
})
.state('workspace.images.edit', {
url: '/:key',
templateUrl: 'app/workspace/editor.view.html',
controller : 'Workspace.EditorController as vm'
})
.state('workspace.documents', {
url: 'documents',
views: {
'sidebar': {
templateUrl: 'app/workspace/sidebar.view.html',
controller : 'Workspace.SidebarController as vm'
},
'content': {
templateUrl: 'app/workspace/documentslist.view.html',
controller : 'Workspace.DocumentsListController as vm'
}
}
});
As you can see, I have to repeat the "sidebar" template each time. I would like to be able to configure it form the abstract workspace state.
workspace.view.html contains the "sidebar" and "content" views :
<div class="sidebar" ui-view="sidebar">
<!-- view = sidebar -->
</div>
<div class="content" style="height: 100%" ui-view="content">
<!-- view = content-->
</div>
I think I should have a views object into the "workspace" state to define the "sidebar" templates and controllers and leave the "content" empty.
And have tried with and without named views but without success. When I do that, the sidebar template is never displayed but seems to be loaded (a wrong name cause a 404 in my console).
This will inject sidebar into parent... and child can use it or even change it:
.state('workspace', {
url: '/',
views: {
'': { templateUrl: 'app/workspace/workspace.view.html' }
'sidebar#workspace': {
templateUrl: 'app/workspace/sidebar.view.html',
controller : 'Workspace.SidebarController as vm'
},
}
})
.state('workspace.images', {
url: 'images',
views: {
'content': {
templateUrl: 'app/workspace/imageslist.view.html',
controller : 'Workspace.ImagesListController as vm'
}
}
})
...
We used views : {} even on parent state. The default unnamed is the original workspace.view.html
We also added named view 'sidebar#workspace' - the absolute name here means, that the name is 'sidebar' and its target is searched inside of the 'workspace' state templates
I try to create an app with angular, and somehow the child state in not loading.
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('home', {
url : "/",
templateUrl: "/admin/home/"
})
.state('users', {
url : "/users/",
templateUrl: "/admin/users",
controller : function ($stateParams) {
console.log($stateParams);
console.log("users");
}
})
.state('users.new', {
url : "^/users/user/",
templateUrl: "/admin/users/new",
controller : function () {
console.log("users.new");
}
})
.state('users.user', {
url : "^/users/user/:uuid",
templateUrl: function ($stateParams) {
console.log($stateParams);
return "/admin/users/" + $stateParams.uuid
},
controller : function () {
console.log("users.user");
}
});
When I visiting the page
/users/user/55d8b1c706387b11480d60c1
I see the request to load the page, but only the "users" controller got executed.
This problem appears only with child states, switching between parent state working without problems.
I Using the latest versions of angular and ui-routes.
any ideas?
Please read this DOC
You mistake is in hierarchy. Child states use parent template as root and try find nested <ui-view>
You may add abstract state user without url, with empty template <ui-view></ui-view>, for nested viws. Then rename user, to E.G. user.index, it works for me
1st (It may works)
$stateProvider
.state('home', {
url : "/",
templateUrl: "/admin/home/"
})
.state('users', {
template: "<ui-view></ui-view>",
})
.state('users.index', {
url : "/users/",
templateUrl: "/admin/users",
controller : function ($stateParams) {
console.log($stateParams);
console.log("users");
}
})
.state('users.new', {
url : "^/users/user/",
templateUrl: "/admin/users/new",
controller : function () {
console.log("users.new");
}
})
.state('users.user', {
url : "^/users/user/:uuid",
templateUrl: function ($stateParams) {
console.log($stateParams);
return "/admin/users/" + $stateParams.uuid
},
controller : function () {
console.log("users.user");
}
});
2nd way is USE absulutly named views E.G.
views: {
"": { templateUrl: 'pages/menu.html' }, // relative noName view
"header": { templateUrl: "pages/header.html"}, //relative named view
"content#": { // Absolute name
template: "<ui-view></ui-view>",
controller: 'AuthController'}
}
I have a UI-Router document set up to show the "pages" sections of a demo.
(function() {
'use strict';
angular.module('pb.ds.pages').config(function($stateProvider) {
$stateProvider.state('pages', {
abstract: true,
url: '/pages',
templateUrl: 'modules/pages/templates/pages.html',
controller: 'PagesController as pages',
data: {
pageTitle: 'Pages',
access: 'public',
bodyClass: 'pages'
}
})
.state('pages.signin', {
url: '/signin',
templateURL: 'modules/pages/templates/signin.html',
controller: 'SignInController as signin'
})
.state('pages.forgotpassword', {
url: '/forgotpassword',
templateURL: 'modules/pages/templates/forgotpassword.html',
controller: 'ForgotPasswordController as forgot'
})
.state('pages.404', {
url: '/404',
templateURL: 'modules/pages/templates/404.html',
controller: '404Controller'
});
});
})();
The parent state, "pages" has the ui-view on it, but otherwise I don't need to "show" it. I am only interested in showing its children, such as pages.signin or pages.forgotpassword.
Typing in the url "/forgotpassword" bounces me back to my homepage, which is the "otherwise" state in my app.module.js
// UI ROUTER CONFIG
angular.module('app').config(function($stateProvider) {
$stateProvider.state('otherwise', {
url: '*path',
template: '',
controller: function($state) {
$state.go('dashboard');
}
});
});
No errors in console, and all the pages in question are linked in my index.html.
I'm sure I must have missed something obvious. Any clues?
UPDATE
If I enter /pages/forgotpassword it does go to the correct path but the view is not being populated by the template...
There is a working plunker
We have to adjust state definition like this:
$stateProvider.state('pages', {
abstract: true,
//url: '/pages',
templateUrl: 'modules/pages/templates/pages.html',
controller: 'PagesController as pages',
data: {
pageTitle: 'Pages',
access: 'public',
bodyClass: 'pages'
}
})
.state('pages.signin', {
url: '/signin',
// templateURL: 'modules/pages/templates/signin.html',
templateUrl: 'modules/pages/templates/signin.html',
controller: 'SignInController as signin'
})
.state('pages.forgotpassword', {
url: '/forgotpassword',
//templateURL: 'modules/pages/templates/forgotpassword.html',
templateUrl: 'modules/pages/templates/forgotpassword.html',
controller: 'ForgotPasswordController as forgot'
})
The most important is replacement of the templateURL with templateUrl. Javascript (and UI-Router) is case sensitive.
We also do not need define url for parent... it could be just child state definition
Finally, we must be sure, that our parent contains some target ui-view="" where child states will be placed. E.g. this is the plunker pages.html:
<div>
<h3>pages</h3>
<hr />
<div ui-view=""></div>
</div>
These links will then work as expected:
//href
<a href="#/signin">
<a href="#/forgotpassword">
//ui-sref
<a ui-sref="pages.signin">
<a ui-sref="pages.forgotpassword">
We can leave the parent url:
$stateProvider.state('pages', {
abstract: true,
url: '/pages',
...
but the href links for child states must contain the parent url as well:
<a href="#/pages/signin">
<a href="#/pages/forgotpassword">
Check it here in action
You need to prefix the state url with the url of the parent state. So the correct url that you need open with the browser should be: #/pages/forgotpassword
Check the doc URL Routing for Nested States