I am facing a very peculiar problem in angular1 and it might need a lot context to understand for someone to answer. I have been working on angular for around 4 weeks now but a very strange problem entangles me.
I have a left vertical menu on a page and a click on it loads the content on right side of the page.
On each click I initiate a state. In this case
$state.go("contrat-synthese", {
id: offer.refEboard
}, {
reload: true
});
The above peice of a code is inside a function which works on the click.
The state "contrat-synthese" is shown below
angular.module('engcApp').config(['$stateProvider', function($stateProvider) {
var lotSelectionState = "synthese-lot";
$stateProvider.state('contrat-synthese', {
parent: 'contrat-lots-resume',
url: '/synthese',
views: {
'content#contrat-lots-resume': {
templateUrl: 'app/entities/views/synthese/synthese.html',
},
'synthese-detail#contrat-synthese': {
templateUrl: 'app/entities/views/synthese/synthese-details.html',
controller: 'ContratSyntheseDetailsController',
controllerAs: 'vm'
},
'synthese-lots-navigation#contrat-synthese': {
templateUrl: 'app/entities/views/common/contrat-lots-navigation.html',
controller: 'ContratLotsNavigationController',
controllerAs: 'vm',
resolve: {
afficherLotComplet: function() {
return false;
},
afficherAnneeComplet: function() {
return false;
},
afficherSelectionAnnee: function() {
return true;
},
afficherLots: function() {
return true;
},
stateNameToUse: function() {
return lotSelectionState;
}
}
},
'synthese-services#contrat-synthese': {
templateUrl: 'app/entities/views/synthese/synthese-services.html',
controller: 'ContratSyntheseServicesController',
controllerAs: 'vm'
}
}
}).state(lotSelectionState, {
parent: "contrat-synthese",
params: {
lots: null
},
views: {
'synthese-composition-lot#contrat-synthese': {
templateUrl: 'app/entities/views/synthese/synthese-composition.html',
controller: 'ContratSyntheseCompositionController',
controllerAs: 'vm'
},
'synthese-volumes-lot#contrat-synthese': {
templateUrl: 'app/entities/views/synthese/synthese-volumes.html',
controller: 'ContratSyntheseVolumesController',
controllerAs: 'vm'
},
'synthese-modules-lot#contrat-synthese': {
templateUrl: 'app/entities/views/synthese/synthese-modules.html',
controller: 'ContratSyntheseModulesController',
controllerAs: 'vm'
},
'synthese-formules-lot#contrat-synthese': {
templateUrl: 'app/entities/views/synthese/synthese-formules.html',
controller: 'ContratSyntheseFormulesController',
controllerAs: 'vm'
},
}
});
}]);
But when I call the state go on page load it is not able to load the lotSelectionState in the synthese state above.
I just don't understand why it is not able to load the states when I call it from outside.
Also child states are not loaded when I click on the link again on the left banner.
Solution I tried for the second case, I tried the following approach:
state.go("contrat-synthese", {
id: offer.refEboard
}, {
reload: true
});
However why am I not able to load the child state? I am so confused :(
Can provide and explain more if needed.
Related
I am facing very strange issue, while home page can resolve service data, the exactly the same thing is failed for inner page, here is my route code:
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'app/layout/home/home.html',
controller: 'HomeController',
controllerAs: 'vm',
resolve: {
pressData: function (HomeService) {
return HomeService.pressService().query().$promise;
},
countryData: function (countryservice) {
return countryservice.countryServiceData().query().$promise;
}
}
})
.state('create', {
url: '/event/create',
templateUrl: 'app/layout/create-event/create-event.html',
controller: 'CreateEventController',
controllerAs: 'vm',
resolve: {
countryData: function (countryservice) {
return countryservice.countryServiceData().query().$promise;
}
}
});
So countryData is successfully resolved for home state, while is not for create route.
EDIT.
Here is my factory:
angular
.module('GutenChefApp')
.factory('countryservice', countryservice);
countryservice.$inject = ['$resource'];
function countryservice($resource) {
var service = {
countryServiceData: getCountryService
};
return service;
function getCountryService() {
return $resource('app/data/countries.json');
}
}
I have a articledetail state, which I navigate to:
$state.go('articledetail', { 'article': article.itemNumber });
In articleDetail.html, I'd like to load the subviews, all at the same time:
<div class="tab-content col-xs-7">
<div ui-view="tab1"></div>
<div ui-view="tab2"></div>
<div ui-view="tab3"></div>
<div ui-view="tab4"></div>
<br />
</div>
Below is my state config. I have already tried using both # and without #, but none of my views (not even the main one) gets loaded and I'm not getting any errors.
$stateProvider.state('articledetail', {
url: '/articledetail/:article',
templateUrl: '/articledetail/articleDetail.html',
controller: 'articleDetailController',
controllerAs: 'vm',
views: {
'tab1#': {
templateUrl: '/articledetail/tab1.html'
},
'tab2#': {
templateUrl: '/articledetail/tab2.html'
},
'tab3#': {
templateUrl: '/articledetail/tab3.html'
},
'tab4#': {
templateUrl: '/articledetail/tab4.html'
}
}
});
The frustrating thing is I don't get any errors, so I have no idea what I'm doing wrong. I've already enabled error logging as explained in the ui-router FAQ, but without result.
What am I doing wrong?
You would need this in index.html
<div ui-view=""></div>
And then the state could be changed to this:
$stateProvider.state('articledetail', {
url: '/articledetail/:article',
views: {
// this would instractu UI-Router
// to inject the articleDetail.html into index.html
// into target ui-view="" (would be the same as '#')
'': {
templateUrl: '/articledetail/articleDetail.html',
controller: 'articleDetailController',
controllerAs: 'vm',
},
// these will now be injected into above view,
// and absolute name says: viewName#stateName
// and the state is 'articleDetail'
// so we need 'tab1#articledetail'
'tab1#articledetail': {
templateUrl: '/articledetail/tab1.html'
},
'tab2#articledetail': {
templateUrl: '/articledetail/tab2.html'
},
'tab3#articledetail': {
templateUrl: '/articledetail/tab3.html'
},
'tab4#articledetail': {
templateUrl: '/articledetail/tab4.html'
}
}
});
I'm trying to test an Angular UI Bootstrap modal that is being called from the onEnter of the following state:
.state("profile.index.edit.services", {
url: "/edit/services/:serviceCode",
parent:"profile.index",
onEnter: ['$stateParams', '$state', '$modal',function($stateParams, $state, $modal) {
$modal.open({
templateUrl: 'profile/edit-services-modal.html',
controller: 'ProfileEditServicesController',
resolve: {
profileData: function(CacheService){
return CacheService.getItem(CacheService.Items.Profile.loadedProfile);
},
allServicesList: function(ProfileService){
return ProfileService.getAllServicesList($stateParams.serviceCode,$stateParams.orgId);
},
serviceCode: function() {
return $stateParams.serviceCode;
}
}
}).result.then(function(result) {
if (result) {
return $state.transitionTo("profile.index", { orgId: $stateParams.orgId });
}
else { // cancel
return $state.transitionTo("profile.index", { orgId: $stateParams.orgId }); // don't reload
}
}, function () {
// executes on close/cancel/ESC
return $state.transitionTo("profile.index", { orgId: $stateParams.orgId });
});
}]
})
I've been banging my ahead against this trying many different things to set the test up, but can't seem to figure it out. Any plunkers or suggestions are greatly appreciated!!!!
By the way, the state above is a descendant of these states, which I've been able to write tests for that pass:
.state('profile.index', {
url: '/:orgId',
views: {
'profile-index#profile': {
templateUrl: 'profile/view-profile.html',
controller: 'ProfileController'
},
'header#': {
templateUrl: 'common/layout/header.html',
controller: 'HeaderController'
},
'footer#':{
templateUrl: 'common/layout/footer.html',
controller: 'FooterController'
}
},
resolve: {
profileData: function(ProfileService, $stateParams){
return ProfileService.getProfile($stateParams.orgId, true);
}
}
})
.state('profile.index.edit', {
url: '',
abstract: true
})
did you ever figure this out? you should have passed a named controller, that way you could test that controller (since it would just be a function) directly instead of relying on onEnter being fired.
I want to give 2 parts of my UI the same controller but still let them have each of their own unique controllers.
$stateProvider
.state('standard.page', {
url: '/:page',
resolve: {
page: function($stateParams) {
...
},
},
views: {
'content': {
templateUrl: '/tmpl/page',
controller: 'controllercontent'
},
'sideMenu': {
templateUrl: '/tmpl/menu',
controller: 'controllermenu',
}
}
})
So I want both content and sideMenu to share a controller. If I add a controller above the views then it requires a new template, I want to use the standard template instead of making a unique template for this state. Any ideas how I can get 3 controllers going in this example? Thanks.
I battled with this at some point in time, and I believe I made a template file that isn't directly accessible (via abstract: true). Here's an example...
.state('standard', {
url: '/standard',
abstract: true,
templateUrl: '/tmpl/standard.html',
controller: 'SharedController'
},
})
.state('standard.page', {
url: '/:page',
resolve: {
page: function($stateParams) {
...
},
},
views: {
'content': {
templateUrl: '/tmpl/page',
controller: 'controllercontent'
},
'sideMenu': {
templateUrl: '/tmpl/menu',
controller: 'controllermenu',
}
}
});
In your tmpl/standard.html file, make sure this exists somewhere within the file:
<div ui-view="sideMenu">
<div ui-view="content">
Hope this points you in the right direction.
I have an app with 3 views (A,B,C) and 2 states(1,2)
html
<div ui-view="A"></div>
<div ui-view="B"></div>
<div ui-view="C"></div>
The two states are called list and create. In both states the template and controller of view A + B stay the same but view c should change templates and controllers. I can get view c's content to change but it refreshes view A and view B as it does ie things that are in their controllers run again.
What is the correct way to organise the router to prevent this?
js so far
$urlRouterProvider.otherwise("/basestate/list");
$stateProvider
.state('baseState', function() {
url:"/basestate",
templateUrl: "basestate.html",
controller: 'BaseStateCtrl'
})
.state('baseState.list', function() {
url: "/list",
views: {
"viewA#baseState": {
templateUrl: "viewA.html"
controller: "ViewACtrl"
},
"viewB#baseState": {
templateUrl: "viewB.html"
controller: "ViewBCtrl"
},
"viewC#baseState": {
templateUrl: "list.html"
controller: "listCtrl"
}
}
})
.state('baseState.create', function() {
url: "/create",
views: {
"viewA#baseState": {
templateUrl: "viewA.html"
controller: "ViewACtrl"
},
"viewB#baseState": {
templateUrl: "viewB.html"
controller: "ViewBCtrl"
},
"viewC#baseState": {
templateUrl: "create.html"
controller: "createCtrl"
}
}
})
To achieve that you basically need to freeze your viewA and viewC at the level of baseState and make that state abstract:
.state('basestate', {
url: '/basestate',
abstract: true,
views: {
"viewA": {
templateUrl: "viewA.html",
controller: "ViewACtrl"
},
"viewB": {
templateUrl: "viewB.html",
controller: "ViewBCtrl"
},
"viewC": {
template: '<div ui-view="viewC_child"></div>'
}
}
})
Note that for viewC we are making a placeholder that will contain our nested view (either list or create):
.state('basestate.list',{
url: "/list",
views: {
"viewC_child": {
templateUrl: "list.html",
controller: "ListCtrl"
}
}
})
.state('basestate.create', {
url: "/create",
views: {
"viewC_child": {
templateUrl: "create.html",
controller: "CreateCtrl"
}
}
})
Check this plunkr and be careful with commas in your code :)