Search code examples
jqueryangularjsangularjs-directiveangular-directive

how to call a function (or directive) only when tab is selected in angularjs?


I'm new in angularjs, I have page with 2 tabs.I create tabs using directives, I use $http to get json from my server.my problem is I don't want to request my server until user decide to see my other tab. how can I do this? here is my directives :

var sdmtab = angular.module('sdmTab', []);

sdmtab.directive('tab', function() {
return {
    restrict: 'E',
    transclude: true,
    template: '<div role="tabpanel" ng-show="active" ng-transclude></div>',
    require: '^tabset',
    scope: {
        heading: '@'
    },
    link: function(scope, elem, attr, tabsetCtrl) {
        scope.active = false;
        tabsetCtrl.addTab(scope);
    }
};
});
sdmtab.directive('tabset', function() {
return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'app/components/directiveTemps/tabset.html',
    bindToController: true,
    controllerAs: 'tabset',
    controller: function() {
        var self = this;
        self.tabs = [];
        self.addTab = function addTab(tab) {
            self.tabs.push(tab);
            if (self.tabs.length === 1) {
                tab.active = true;
            }
            self.select = function(selectedTab) {
                angular.forEach(self.tabs, function(tab) {
                    if (tab.active && tab !== selectedTab) {
                        tab.active = false;
                     }
                 });

                 selectedTab.active = true;
             };
         };
     }
  };
 });

sdmtab.directive('teamsq', function() {
return {
    restrict: 'E',
    scope: {},
    templateUrl: 'app/components/directiveTemps/teamSquad.html',
    bindToController: true,
    controllerAs: 'teamsq',
    controller: function($http, $log, userInfo) {
        var self = this;
        userInfo.then(function(answer) {
            var sid = answer.data.data.current_team.sid;
            var tid = answer.data.data.current_team.tid;
            self.team = [];
            self.bang = 'shirin';
            $http.get(webservice + "/team?token=" + token + "&team_id=" + tid + '&season_id=' + sid).success(function(response) {
                var players = response.data.players;
                angular.forEach(response.data.players, function(player) {
                    player['imageURL'] = "http://sdm.tarafdari.com/sites/default/files/players/150x150/" + player.pid + ".png";
                });
                self.team = response.data;
            });
        });

    }
};
});

here is my html :

<tabset>
  <tab heading="Details">
       ...
   </tab>
   <tab heading="Other infos">
       <teamsq></teamsq>
   </tab>
</tabset>

I want teamsq directive,only request when my 'other info' tab is selected.


Solution

  • I did a little editing in my directive,I used action local sope in my tab directive to bind my directive to an external function,

    sdmtap.directive('tab', function() {
        return {
        restrict: 'E',
        transclude: true,
        template: '<div role="tabpanel" ng-show="active" ng-transclude></div>',
        require: '^tabset',
        scope: {
            heading: '@',
            action: '&'
        },
        link: function(scope, elem, attr, tabsetCtrl) {
            scope.active = false;
            tabsetCtrl.addTab(scope);
        }
      };
    });
    

    and simply in my tabset directive template I add action property to ng-click of my tab beside of select function :

    <a href="" role="tab" ng-click="tabset.select(tab);tab.action()">{{tab.heading}}</a>
    

    and in original template I add showSquads() function as action property to directive

    <tab action="showSquads()" heading="{{'Team Squads'| translation}}">
    

    and create showSquads() function in my controller, now when I click on my tabs, other than tab functionality, my custom function can be run for every tab

    here is a plunker