2013-10-11 13 views
4

мне нужно получить контроллер родителя, так что моя директива имеет свойство требовать, следующим образом:Доступ к контроллеру материнской директивы рекурсивно в AngularJS

module.directive('tag', function() { 
    return { 
     require: '?^tag', 
     restrict: 'E', 
     controller: function() { 
      this.payload = getPayload(); 
     }, 
     link: function (scope, element, attrs, ctrl) { 
      usePayload(ctrl.payload); 
     } 
    }; 
}); 

Однако параметр Ctrl функции связи возвращает контроллер текущей директивы , а не родительский. Документация AngularJS ясно из этого:

?^- Попытайтесь найти требуемый контроллер, выполнив поиск родителей элемента или верните нулевой, если не нашли.

Что я делаю неправильно?

+1

'require: '?^Parent'' или назначить контроллер директивы на имя родительского контроллера или оставить контроллер директивы все вместе, а' ctrl' в параметрах ссылки по умолчанию будет принадлежать родительскому. –

+0

Посмотрите на это видео [John Lindquist] (http://egghead.io/lessons/angularjs-directive-communication), что очень хорошо объясняет связь между вложенными директивами. –

+0

@ m.e.conroy: Я должен использовать одно и то же имя в 'require'. Если контроллер не объявлен, 'ctrl' по умолчанию' undefined'. –

ответ

10

либо документы или код вводят в заблуждение здесь ... require с ^ смотрит на текущий элемент, а затем всех родителей, используя inheritedData метод (см https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L942). Таким образом, вы не сможете требовать директиву с тем же именем от родителя, используя этот подход.

Когда у меня была эта проблема в прошлом, я рассмотрел директиву form, которая должна делать то, что вы просите. Его метод контроллера хватает родителя, как так (https://github.com/angular/angular.js/blob/master/src/ng/directive/form.js#L39):

controller: function($element) { 
    var parentForm = $element.parent().controller('form'); 
} 

Принимая это, вы должны быть в состоянии назвать element.parent().controller('tag') найти родительский контроллер либо в контроллере или методов postLink.

+1

Это работает, спасибо! Моя единственная проблема заключается в том, что метод 'controller()' не раскрывается в их API, поэтому не предназначен для общественного использования и может быть изменен. –

+0

Документы можно найти в папках для 'angular.element': http://docs.angularjs.org/api/angular.element. Это определенно задокументировано в нестабильных ветках, но я не проверял стабильность. – Andyrooger

+0

Это так полезно. Спасибо, я хотел создать элемент, который мог бы действовать как контейнер для себя, поэтому это прекрасно. Кроме того, я прочитал, что не рекомендуется передавать элемент на контроллер, чтобы вы всегда могли работать с элементом в функции ссылки –

Смежные вопросы