How it works…

In large-scale applications, it is very common to use dynamic content to populate the interface components. Our first example demonstrates how easy it is to use this type of content, by implementing a simple Bootstrap tab directive as the following code:

<div ng-controller="BootstrapTabCtrl">
  <tabset>
    <tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled">
    {{tab.content}}
    </tab>
  </tabset>
</div>

The $http.get ()method makes a call to an external file, in this case the tab-content.json file, to load the tab contents of the directive.

$http.get('app/home/tab-content.json').
  success(function(data) {
    // Get dynamic data from JSON file
    $scope.tabs = data;

  }).
  error(function(status) {
    // if error, show status
    console.log(status);
  });

In the second example, we created a directive and used an inline template with the inline controller.

.directive('customTabs', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    controller: [ "$scope", function($scope) {
      var panes = $scope.panes = [];

      $scope.select = function(pane) {
        angular.forEach(panes, function(pane) {
          pane.selected = false;
        });
        pane.selected = true;
      }

      this.addPane = function(pane) {
        if (panes.length == 0) $scope.select(pane);
          panes.push(pane);
      }

    }],
    // Using inline template
    template:
    '<div class="tabbable">' +
    '<ul class="nav nav-tabs">' +
      '<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">'+
      '<a href="" ng-click="select(pane)">{{pane.title}}</a>' +
      '</li>' +
    '</ul>' +
    '<div class="tab-content" ng-transclude></div>' +
    '</div>',
    replace: true
  };
})