davidpm4
davidpm4

Reputation: 582

Angular: template with a parent and child directive

I have this simple example...

Code:

angular
      .module('app', [])
      .directive('parentDirective', parentDirective)
      .directive('childDirective', childDirective);

    function parentDirective() {
      return {
        restrict: 'E',
        scope: true,
        //template: 'My job is {{job}}', 
        controller: function($scope) {
          $scope.job = 'trashman';
          $scope.say = function(job) {
            $scope.job = job;
            alert($scope.job);
          }
        }
      };
    }

    function childDirective() {
      return {
        restrict: 'E',
        link: function(scope) {
          scope.say('shoe shine boy');
        }
      };
    }

Markup:

    <parent-directive>
        <child-directive></child-directive>
    </parent-directive>

This works as expected. The problem I'm having is understanding why I can't add a template to the the parentDirective and achieve the same result. If you un-comment the template property, the binding doesn't change and the alert is no longer fired. Can someone briefly explain to me what's happening here? Maybe help flesh out my example? I learn by example :)

Upvotes: 0

Views: 1457

Answers (2)

ArslanW
ArslanW

Reputation: 353

You can set a template property on the parent and inside the template use the child directive. It should ideally render automatically.

Something like:

angular .module('app', []) .directive('parentDirective', parentDirective) .directive('childDirective', childDirective);

function parentDirective() {
  return {
    restrict: 'E',
    scope: true,
    template: '<div>{{job}} is seen<child-directive></child-directive></div>'
    //template: 'My job is {{job}}', 
    controller: function($scope) {
      $scope.job = 'trashman';
      $scope.say = function(job) {
        $scope.job = job;
        alert($scope.job);
      }
    }
  };
}

function childDirective() {
  return {
    restrict: 'E',
    template: '<div>I will be renderred</div>',
    link: function(scope) {
      scope.say('shoe shine boy');
    }
  };
}

Now you can use the parent directive anywhere and it will render the child directive inside it as well.

Something like:

<parent-directive></parent-directive>

Angular will now see it like this, parent directive found, render it, inside it is a child directive used, render the child's html.

Upvotes: 1

Chandermani
Chandermani

Reputation: 42669

When you use the directive template, then it replaces the directives inner content with the template and most probably due to that the inner directive is never rendered.

You need to use ng-transclude in the parent template to emit the child directive html inside the parent directive template. On your directive definition object mark

transclude: true,

and

template: '<div> My job is {{job}} <ng-transclude></ng-transclude></div>'

This is from the $compile documentation

Replace the contents of the directive's element (default).

Replace the directive's element itself (if replace is true - DEPRECATED).

Wrap the contents of the directive's element (if transclude is true).

Upvotes: 1

Related Questions