Reputation: 15703
I'm trying to refactor our current layout to add in a dynamic show/hide section above the header on our page. We are using Angularjs 1.4.2 with ui-router and currently we are using separate route files, although we have a main route. The main.html section of the screen, up to now, was the only section with the dynamic content. In order to get my new route working, I'm having to add it and main to each of the existing routes.
My question is, would a better design be something along this line of a single parent route to handle a resolve, with nested states for the dynamic main content and a new view for my new route and content? As the application grows, do you still continue to put the new routes into the parent route or is there a better way to organize it like we were doing with individual route files or a combination of both?
This is what I'm trying, but it's not working yet, as I'm getting a blank page, but the design for future growth with the application is what I'm trying to get right here:
(function () {
'use strict';
angular
.module('myApp')
.config(config);
config.$inject = ['$stateProvider'];
/* @ngInject */
function config($stateProvider) {
$stateProvider
.state('root', {
template: '<ui-view></ui-view>',
abstract: true,
resolve:{
myLoader: ['myLoader', function(myLoader){
// $http returns a promise for the url data
return myLoader.load();
}]
}
}
.state('main'), {
url: '/?param1¶m2¶m3¶m4',
templateUrl: 'app/routes/main/main.html',
controller: 'MainCtrl',
redirectTo: 'main'
})
$stateProvider
.state('basicsearch', {
url: '/basic-search',
templateUrl: 'app/routes/basicsearch/basicsearch.html',
controller: 'searchQuickCtrl'
})
$stateProvider
.state('advancedsearch', {
url: '/advaned-search',
templateUrl: 'app/routes/advancedsearch/advancedsearch.html',
controller: 'advancedSearchkCtrl'
})
$stateProvider
.state('anothersearch', {
url: '/another-search',
templateUrl: 'app/routes/anothersearch/anothersearch.html',
controller: 'anotherSearchCtrl'
})
.state('myChange', {
url: '/myChange?param5¶m6¶m7¶m8',
views: {
"myChangeView": {
templateUrl: '/app/routes/myChange/myChange.html',
controller: 'myChangeCtrl'
}
}
});
}
})();
Here is a basic layout of what we have:
Upvotes: 1
Views: 1495
Reputation: 123861
I am not sure about the issue. But I created working plunker, to show you how we can use state nesting and resolve.
So this is our parent controller for root state and the factory used in resolve
.factory('myLoader', function(){
return {
load: function () {return [1,2] }
};
})
.controller('ParenCtrl', ['$scope', 'myLoader', function ($scope, myLoader) {
$scope.myLoader = myLoader;
}])
.controller('MainCtrl', ['$scope', 'myLoader', function ($scope, myLoader) {}])
.controller('searchQuickCtrl', ['$scope', 'myLoader', function ($scope, myLoader) {}])
.controller('advancedSearchkCtrl', ['$scope', 'myLoader', function ($scope, myLoader) {}])
.controller('anotherSearchCtrl', ['$scope', function ($scope) {}])
Next, we will use controller for abstract root state, to assign result into scope:
.state('root', {
template: '<div ui-view></div>',
abstract: true,
controller: 'ParenCtrl',
resolve:{
myLoader: ['myLoader', function(myLoader){
// $http returns a promise for the url data
return myLoader.load();
}]
}
})
And all states will use that as their parent, and inherit the scope:
.state('main', {
parent: 'root',
url: '/?param1¶m2¶m3¶m4',
templateUrl: 'app/routes/main/main.html',
controller: 'MainCtrl',
//redirectTo: 'main'
})
.state('basicsearch', {
url: '/basic-search',
templateUrl: 'app/routes/basicsearch/basicsearch.html',
parent: 'root',
controller: 'searchQuickCtrl'
})
.state('advancedsearch', {
url: '/advaned-search',
templateUrl: 'app/routes/advancedsearch/advancedsearch.html',
parent: 'root',
controller: 'advancedSearchkCtrl'
})
.state('anothersearch', {
url: '/another-search',
parent: 'root',
templateUrl: 'app/routes/anothersearch/anothersearch.html',
controller: 'anotherSearchCtrl'
})
And properly use it inside of this view:
<div >
<h3>current state name: <var>{{$state.current.name}}</var></h3>
<h4>resolved in parent</h4>
<pre>{{myLoader | json }}</pre>
<h5>params</h5>
<pre>{{$stateParams | json}}</pre>
<h5>state</h5>
<pre>{{$state.current | json}}</pre>
</div>
while all these controller do not use that resolved value
.controller('MainCtrl', ['$scope', 'myLoader', function ($scope, myLoader) {}])
.controller('searchQuickCtrl', ['$scope', 'myLoader', function ($scope, myLoader) {}])
.controller('advancedSearchkCtrl', ['$scope', 'myLoader', function ($scope, myLoader) {}])
.controller('anotherSearchCtrl', ['$scope', function ($scope) {}])
So, each controller can be provided with stuff resolved in parent (as parameter). That is shown above. But also, becuase parent already used that and assigned that to some $scope variable... all is alraeady in place.
Also check:
Upvotes: 2