chinabuffet chinabuffet - 3 months ago 20
AngularJS Question

Angular scope from ng-controller on custom directive that uses transclusion

I'm pretty new to Angular still, so I apologize if this is a silly question... I have a custom directive that uses transclusion, and I'm trying to understand why data binding works if I assign an ng-controller to a parent element, but not when I assign the controller directly onto it:

Code:

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>




Plunker: https://plnkr.co/edit/ICztHcKU4W2EgFmy8OqQ?p=preview

Any ideas?

gyc gyc
Answer

A directive is defined as a function that returns an object (with template, bindings, controller and other properties) that is compiled into an element.

Whatever attribute you put inside your element is passed to the directive bindings (or isolated scope), it is not interpreted.

You could technically pass the controller as an attribute to your directive but it doesn't look like good practice since directives have a controller property.

For example this would work: 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
      };
    });

But you see you could use

controller: function() {}

directly inside the directive which would make it more independent.