Pull to refresh

Comments 11

> В-третьих, link всегда привязана к директиве, в то время как контроллер может быть общим. Думаю, в этом ключевое отличие.
Это как?
Видимо имеется ввиду, что никто не может запретить вам переиспользовать контроллер в любом другом месте.
а что мешает функцию ликновки переиспользовать? )
link_func = function(scope, element, attrs, ctrls) {
   console.log(ctrls); //[parentCtrl, childrenCtrl]. Тем не менее контроллер из children будет доступен в дочерней директиве
}

app.directive('baby', function() {
  return {
    restrict: 'E',
    link: link_func
  }
})

app.directive('baby2', function() {
  return {
    restrict: 'E',
    link: link_func
  }
})

Ничто не мешает, конечно. Но контроллер можно переиспользовать через ng-controller хоть с as, хоть без него. И к директивам это может никакого отношения не иметь. А функция линковки вроде только для директив может пригодиться (ну, если её нормально использовать, конечно).
Функцию link или скорее весь объект определения директивы можно так же использовать с разными директивами. На этом построен метод расширения директив в angular-bootstap, например.

Директивы tooltip и popover используют объект генерируемый одной и той же функцией $tooltip()

.directive( 'tooltip', [ '$tooltip', function ( $tooltip ) {
  return $tooltip( 'tooltip', 'tooltip', 'mouseenter' );
}])

.directive( 'popover', [ '$tooltip', function ( $tooltip ) {
  return $tooltip( 'popover', 'popover', 'click' );
}]);


Но тут дело в том, что области видимости у функций link будет разная, в случае же с контроллером в каждую директиву передается один и тот же объект контроллера в котором можно хранить общие данные, да и по ресурсам памяти это экономичнее.
в статье примеры чересчур замороченные. вообще, когда надо организовать взаимодействие нескольких директив, связанных общей логикой, рекомендуют выносить эту логику в общий для них контроллер. ведь основная задача директив — создавать мостики между приложением и DOM — которая решается в функциях link. большего от них не требуется. думаю, что это имелось ввиду.
«Поэтому в $scope, например, можно записать настройки для дочерних директив.»

Если уж у вас дочерние \ родительские директивы с контроллерами, то можно и вообще без $scope обойтись — читать настройки прямо из родительского контроллера. Это ещё один плюс контроллеров директивы — можно достичь гораздо более чистого и удобного MVVM используя в качестве контроллеров JS класс без привязки к $scope, вешая все публичные члены на 'this' (а остюда и использовать сторонние JS классы (не знающие про Ангулар, но использующие this) в виде контроллера).

Вот пример plnkr.co/edit/2TWXGZzEaPMujPICTKMQ?p=preview. В нем класс CountController это JS класс, который вообще не привязан к библиотекам — использовать можно хоть в браузере, хоть с NodeJS (большой плюс для code reuse). Кроме того, внешний и внутренний интерфейс получается очень чистый — что внутри директивы, что снаружи работаем с одни и тем же JS объектом.

Эти подходы можно совмещать, если нужно дерево вложенных директив, взаимодействующих друг с другом.
Вообще, ng-controller — это такой синтаксический сахар, а в целом, суть ангуляра — это директивы. Самое важное и основополагающее в ангуляре — это $compile. Просто если сразу с этого начинать, ничего не поймешь :)
Вполне возможно, что потом захотите использовать в директиве методы чужого контроллера, который затрет ссылку на ваш контроллер.

Ну, или не затрёт.

app.directive('children', function() {
  return {
    controller: 'childrenCtrl',
    require: ['^parent', 'children'],
    link: function(scope, element, attrs, ctrls) {
      var parentCtrl = ctrls[0];
      var childrenCtrl = ctrls[1];
      // ...
    }
  }
})
Хороший пример! Не догадался проверить
Sign up to leave a comment.

Articles