Угловая область от ng-controller в пользовательской директиве, которая использует включение

Я все еще новичок в Angular, поэтому прошу прощения, если это глупый вопрос... У меня есть пользовательская директива, которая использует трансклюзию, и я пытаюсь понять, почему привязка данных работает, если я назначаю ng-контроллер для родительский элемент, но не тогда, когда я назначаю контроллер непосредственно на него:

Код:

angular.module('HelloWorld', [])

.controller('HelloController', function($scope) {
  $scope.name = 'you'
})

.directive('hello', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: '<ng-transclude />'
  };
});

HTML:

<!-- why does this one work? -->
<div ng-controller="HelloController">
  <hello>Hi there, {{name}}!</hello>
</div>

<!-- but not this one? -->
<hello ng-controller="HelloController">
  <p> Hi there, {{name}}!</p>
</hello>

Планкер: https://plnkr.co/edit/ICztHcKU4W2EgFmy8OqQ?p=preview

Любые идеи?


person chinabuffet    schedule 17.08.2016    source источник


Ответы (1)


Директива определяется как функция, которая возвращает объект (с шаблоном, привязками, контроллером и другими свойствами), который компилируется в элемент.

Какой бы атрибут вы ни поместили в свой элемент, он передается привязкам директив (или изолированной области), он не интерпретируется.

Технически вы можете передать контроллер как атрибут вашей директиве, но это не похоже на хорошую практику, поскольку директивы имеют свойство контроллера.

Например, это будет работать: https://plnkr.co/edit/WknbSDI4HlQyp2vQIkbR?p=preview

angular.module('HelloWorld', [])

.controller('HelloController', function($scope) {
  $scope.name = 'you'
})

    .directive('hello', function() {
      return {
        restrict: 'E',
        scope: {
          ngController: '&'
        },
        transclude: true,
        template: '<ng-transclude />',
        controller: ngController
      };
    });

Но вы видите, что могли бы использовать

controller: function() {}

непосредственно внутри директивы, что сделало бы ее более независимой.

person gyc    schedule 17.08.2016
comment
Ясно спасибо. Первоначальная причина, по которой я пошел по этому пути, заключалась в том, что я использовал директиву md-button Angular Material ( material.angularjs.org/latest/api/directive/mdButton ) и пытаюсь назначить ng-controller одному и привязать данные к заголовку для него, но заголовок так и не появился, пока я не переместил контроллер вверх уровень. Думаю, такой вариант использования обычно не ожидается/рекомендуется? - person chinabuffet; 17.08.2016
comment
Контроллер управляет элементом HTML. Директива (с ограничением E) перед компиляцией не является элементом HTML. Не рекомендуется передавать контроллер в качестве атрибута директивы, потому что у вас будет код повсюду. - person gyc; 17.08.2016
comment
@chinabuffet Если вам нужна директива, чтобы иметь собственный контроллер (аналогичный компоненту) и сделать его более автономным и многоразовым, просто используйте свойство контроллера. - person gyc; 17.08.2016