0

I want to create a Tab interface with Angular and i chose angular-ui-bootstrap for the tabs. I crated a TabController with the <tabset> inside. I created a TabService as a source for the tabs.

I create on tab with a list of tickets in it (this part works well), i now want to open a new tab by clicking on the items within the list. The Controller should do some stuff and then create a new Tab with the ticket detail view inside

TabService

angular.module('vendor.services').factory('TabService', [ '$q', function ($q) {
    'use strict';

    var tabs = [
        {
            title: "Tab Title",
            icon: "glyphicon-user",
            content: '<ticket-list></ticket-list>',
            closable: false
        }
    ];

    function getTabs() {
        var deferred = $q.defer();
        deferred.resolve(tabs);
        return deferred.promise;
    }

    function addTab(tab) {
        var deferred = $q.defer();
        tabs.push(tab);
        return deferred.promise;
    }

    return {
        getTabs : getTabs,
        addTab : addTab
    };

}]);

Controller

angular.module('vendor').controller('TabController', ['$scope', 'TabService', function ($scope, TabService) {
    'use strict';

    TabService.getTabs().then(function (tabs) {
        $scope.tabs = tabs;
    });

    $scope.addTab = function(type, index) {

        var tab = {
            title: "Tab Title",
            icon: "glyphicon-user",
            content: '<ticket>',
            closable: true
        };

        TabService.addTab(tab);
    };

}]);

Template (jade)

.col-lg-12.tabs(ng-controller="TabController")
    tabset
        tab(ng-repeat="tab in tabs")
            tab-heading
                span.glyphicon(ng-class="tab.icon", ng-show="tab.icon")
                span(compile="tab.title")
                a(ng-click="removeTab($index)", href='', ng-show="tab.closable")
                    i.close &times;
            .tab-content(compile="tab.content")

Directive

angular.module('vendor.directives').
    directive('ticketList',[ function () {
        'use strict';

        function ticketCtrl ($scope, TicketService) {

            TicketService.getTickets().then(function(tickets) {
                $scope.tickets = tickets;
            });

            $scope.openTicket = function(id) {
                $scope.addTab("ticket", id);
            };

        }

        return {

            restrict: 'E',

            controller: ['$scope', 'TicketService', function($scope, TicketService) {
                return ticketCtrl($scope, TicketService);
            }],

            templateUrl : "directives/ticketList.html",

            scope : {
                ngModel: '='
            },

            require: '?^TabController',

            link: function () {
            }
        };


    }]);

Within the tabs i compile some directives, e.g. a list of items. I now want to be able to call the addTab function on the TabController. I tried to do require: '?^TabController' but it cant resolve the controller.

I guess there is some issue when angular-ui creates an isolated scope, but maybe i am just missing something. I just started using directives, i thought about requiring the TabService inside of the directive, but this would make my TabController kind of useless as it is not the responsibility of the TabService.

4
  • now i figured out why this doesnt work, i can only access controllers within other directives, not controllers in general Commented Nov 14, 2013 at 10:49
  • I'm struggling with that too, where did you find that information? Commented Feb 10, 2015 at 5:31
  • You can do this tab thin with angular bootstrap. Take a look at this project on github using ui-router, it has some extra sugar on top of it to create sticky states: christopherthielen.github.io/ui-router-extras/#/home Commented Feb 10, 2015 at 6:07
  • I'm sorry, I didn't explain well. Where did you find the information that directives can only access controllers of other directives and no common controllers? Commented Feb 10, 2015 at 6:11

1 Answer 1

1

You can make TabController a directive with controller:

.directive('tabset', function() {
    return {
        controller: function() {}
    };
}

and then require it in ticketList and pass it to the linking function

require: '^tabset',
link: function(scope, element, attrs, tabsetCtrl) {
    // you can use tabsetCtrl here
}

Watch Egghead lecture on Directive communication http://egghead.io/lessons/angularjs-directive-communication

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

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.