pfried
pfried

Reputation: 5079

Acces Angular Controller from within a tab nested directive

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.

Upvotes: 0

Views: 1438

Answers (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

Upvotes: 1

Related Questions