Reputation: 1011
I have two Bootstrap tabs on my Angular page as follows:
<div>
<ul class="nav nav-tabs">
<li class="active strong">
<a data-target="#home" data-toggle="tab">Tab 1</a>
</li>
<li class="strong">
<a data-target="#pairs" data-toggle="tab">Tab 2</a>
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in active" id="home">
<div ng-include="partial_1.html"></div>
</div>
<div class="tab-pane fade" id="pairs">
<div ng-include="partial_2.html"></div>
</div>
</div>
</div>
Both of the partials have their own controllers defined in the partial_X.html. The two tabs have their own data and business logic, but if the user changes data on server while being on the second tab, the first tab's content should be reloaded from the server (or at least when the user goes to the first tab).
When the tab is clicked, the reload doesn't happen of course, since the controllers have already been instantiated. The data gets reloaded only after a browser refresh on the page as the controller gets initialized again.
Is there a way to reload the controller when the Tab 1 is clicked? I could also combine the two sub controllers into a single one, but that sounds like a dirty workaround for my problem.
Upvotes: 4
Views: 5240
Reputation: 12797
Add data-tabname="tabName"
in your tab anchor, listen to shown.bs.tab
event fired by bootstrap when the tab is displayed and fire up your data refresh service to update.
Simple ex:
$('a[data-toggle="tab"]').on('shown.bs.tab', this.showTabHandler.bind(this));
function showTabHandler(event) {
switch (event.target.dataset.tabname) {
case 'tab1':
this.refreshTab1();
break;
case 'tab2':
this.refreshTab2();
break;
default:
console.log('Unknown tab switched.', event.target.dataset.tabname);
}
}
Working demo link: https://codepen.io/arpi-t/pen/WBbQOQ
Upvotes: 0
Reputation: 40318
Have the controller that changes the data broadcast an event and the controller that needs to update listen to that event. The event will have to be broadcasted on the $rootScope
:
Controller that changes the data:
changeData().then(function() {
$rootScope.$broadcast("importandDataChanged");
});
Controller that needs to update:
$scope.$on("importandDataChanged", function() {
// signal that data changed, lazy load when the tab is actually clicked
$scope.importantData = null;
});
// let $scope.active be a flag that is true when the tab is active
$scope.$watch("active", function(newvval) {
if( newval && $scope.importantData === null ) {
loadData();
}
});
The implementation of the active flag depends on the toolkit you are using (with Bootstrap, I'd suggest going with Angular UI Bootstrap).
Upvotes: 3
Reputation: 13681
Don't think about it in terms of reloading the controller, rather think about simply refreshing the data in the controller's scope. There are many ways one controller can communicate with the other (i.e. broadcasting/emitting events, using a shared service, or altering common scope). Whenever a controller does something that requires refreshing data for another contorller, you simply use one of these available methods to inform the other controller to do an ajax request and set the new values on it's scope.
Upvotes: 0
Reputation: 8981
You can either write a directive that listens for event from the bootstrap jquery plugin (see docs), or use an integration library like angular-strap that does it for you. Then, just watch for the event (or changes to the model) and update your scope with the data from the server.
Upvotes: 0