5

I am using jquery UI tab in angularJS and used ng-repeat to generate list items and tab containers. Tabs are working but the tab containers are not working properly.

template - tabs.html

<ul ng-sortable="pages">
    <li ng-controller="pageCtrl" ng-repeat="page in pages">
        <a class="pageName" href="#{{page.id}}">{{page.name}}</a>
    </li>
</ul>
<div id="{{page.id}}" ng-repeat="page in pages">
    <p>{{page.id}}</p>
</div>

Directive

.directive('ngTabs', function($rootScope) {
        return {
            restrict: 'E',
            templateUrl: "js/templates/tabs.html",
            link: function(scope, elm) {
                elm.tabs();
            }
        };
    })

jsfiddle link: http://jsfiddle.net/sannitesh/NLw6y/

sannitesh
  • 93
  • 1
  • 7

1 Answers1

1

The problem is that when the ngTabs directive is executed the content of that div is not generated yet. Wrapping the call to .tabs() in a setTimeout will do the trick.

myApp.directive('ngTabs', function() {
    return function(scope, elm) {
        setTimeout(function() {
            elm.tabs();
        },0);
    };
});

see jsFiddle. This might not be the best way/the angular way.

You could take a look at the compile service especially if the actual tabs change at runtime.

Liviu T.
  • 23,584
  • 10
  • 62
  • 58
  • Should he not be using the $timeOut service? – uriDium Sep 16 '13 at 08:46
  • @uriDium If he wants to trigger a $scope.$apply then yes but if it's a purely visual effect then there is no need, the directive is not modifying scope data so there is nothing to apply – Liviu T. Sep 16 '13 at 10:59
  • I just thought that $timeout was guaranteed to execute outside of any digest or apply phases and immediately after the current phase is completed. I just thought it was safer. – uriDium Sep 16 '13 at 11:59
  • http://docs.angularjs.org/api/ng.$timeout it's actually the opposite :). After looking in the 1.2.0rc1 codebase it seems it takes a third parameter invokeApply(defaults to true) besides the 2 normal timeout params: fn and delay. So in order to mimic the setTimeout functionality but still call $timeout you need $timeout(fn, 0, false) – Liviu T. Sep 16 '13 at 12:13