4

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.

4 Answers 4

3

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).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, all answers are great. :) I think I'm gonna go with something like above.
0

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.

Comments

0

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.