Доступ к Angular Controller из вложенной директивы вкладок

Я хочу создать интерфейс вкладок с помощью Angular, и я выбрал angular-ui-bootstrap для вкладок. Я упаковал TabController с <tabset> внутри. Я создал 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
    };

}]);

Контроллер

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);
    };

}]);

Шаблон (нефритовый)

.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")

Директива

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 () {
            }
        };


    }]);

На вкладках я компилирую некоторые директивы, например. список предметов. Теперь я хочу иметь возможность вызывать функцию addTab в TabController. Я пытался сделать require: '?^TabController', но он не может разрешить контроллер.

Я предполагаю, что есть некоторая проблема, когда angular-ui создает изолированную область, но, возможно, я просто что-то упускаю. Я только начал использовать директивы, я думал о том, чтобы потребовать TabService внутри директивы, но это сделало бы мой TabController бесполезным, поскольку TabService не несет ответственности за это.


person pfried    schedule 14.11.2013    source источник
comment
теперь я понял, почему это не работает, я могу получить доступ только к контроллерам в других директивах, а не к контроллерам вообще   -  person pfried    schedule 14.11.2013
comment
Я тоже борюсь с этим, где вы нашли эту информацию?   -  person David Barreto    schedule 10.02.2015
comment
Вы можете сделать эту вкладку тонкой с помощью angular bootstrap. Взгляните на этот проект на github с использованием ui-router, у него есть дополнительный сахар для создания липких состояний: christopherthielen.github.io/ui-router-extras/#/home   -  person pfried    schedule 10.02.2015
comment
Извините, я плохо объяснил. Где вы нашли информацию о том, что директивы могут обращаться только к контроллерам других директив, а не к общим контроллерам?   -  person David Barreto    schedule 10.02.2015


Ответы (1)


Вы можете сделать TabController директивой с контроллером:

.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
}

Посмотрите лекцию Egghead о директивном общении http://egghead.io/lessons/angularjs-directive-communication

person Pavel 'Strajk' Dolecek    schedule 14.11.2013