Reputation: 251
I've assembled an angularjs app with ui-bootstrap & ui-router which has some tabbed sub-views where 'index' has a 'ui-view', then for some views, a template with 'uib-tabset' and another 'ui-view' is loaded into the main 'ui-view'.
My tabset isn't rendered with a repeater, but I do have a 'tabs' array setup in the controller with 'active: false' for all 5 of them, for example:
$scope.tabs = [{ active: false }, { active: false }, { active: false }, { active: false }, { active: false }];
The views load OK and the tabs activate OK because they have the 'active' attrib, for example:
<uib-tab heading="Users" ng-click="go('/settings/users')" active="tabs[3].active"></uib-tab>
But I also have a ui-bootstrap dropdown in the header, which transitions to the views as well as fires an 'itemSelected' event, for example:
<li><a href="#/settings/users" ng-click="itemSelected(3)">Users</a></li>
$scope.itemSelected = function(item) {
$rootScope.$broadcast("itemSelected", { tabIdx: item });
The 'tabs' controller responds to the broadcast & sets the active tab:
$scope.$on('itemSelected', function (event, args) {
$scope.tabs[args.tabIdx].active = true;
This (tab activation via dropdown) works OK when I'm within the sub views, but when I first enter into the sub views, this process fails to set the active, I think because of the order things are loaded and become ready for manipulation.
I don't have a base controller, but have defined controllers for every view since I will need to be adding more behaviors for them.
In one of the sub view controllers (for example, sub view #3 'Users'), I added the tabs controller via the '$controller' service, for example:
$controller('TabsCtrl', { $scope: $scope })
With this I seem to get a handle on the '$scope.tabs', but am still not able to set the active tab, for example:
$scope.tabs[3].active = true;
I realize I might set up a base controller and do these things in there, but then I might be affecting just one tabset in scope where I might want more later.
Or I would need logic to check the route state and only set active tab in certain states.
Or I could set an 'activeTab' variable on the rootScope and do something with it in the tabs template or controller to make it active.
But I would rather leverage automatic binding in some way, or at least listen and respond to the state changes in a more correct angularjs way, without adding hacks or workarounds.
When changing route state via a dropdown, how can I set a tab as active in a sub view?
Upvotes: 0
Views: 554
Reputation: 251
I suppose I could pass the tab state around in the URL then process it somehow. I noticed I could control the tabs from the same controller and view but since my drop down is in the index header, and my tabset is in a ui-view, they don't play well. I suppose there are ways to pass data into views, but the issue with what I had is that controllers clean up the scope data when transitioning routes, so I would lose my tab state no matter what I tried.
A more angularjs approach was to add a factory to the base app module, for example:
.factory('tabsFactory', function() {
var tabsService = {};
var _tabsArray = [{ active: false }, { active: false }, { active: false }, { active: false }, { active: false }];
tabsService.activateTab = function(idx) {
for(var i = 0; i < _tabsArray.length; ++i) {
if (idx != i) {
_tabsArray[i].active = false;
} else {
_tabsArray[i].active = true;
}
};
};
tabsService.getTabsArray = function() {
return _tabsArray;
}
return tabsService;
Now my dropdown controller 'itemSelected' function sets the activeTab:
$scope.itemSelected = function(idx) {
tabsFactory.activateTab(idx);
In my tabs controller, I don't need to use '$scope.$on' to react to the broadcast, I just get the tabs from the factory, and the component renders the model state automatically:
$scope.tabs = tabsFactory.getTabsArray();
Also, since each view/sub-view has a controller, I can accommodate browser refresh by activating the appropriate tab in each sub-view controller:
tabsFactory.activateTab(1);
With this arrangement, I have working tab behaviors no matter how I navigate around the app. Thx
Upvotes: 1