Elliot
Elliot

Reputation: 13835

Angularjs - Using directive to instantiate other directives?

So lets say in my HTML I have something like this:

<tabcontent></tabcontent>

Then the javascript for this directive is this:

tabsApp.directive('tabcontent', function(){

  var myObj = {
    priority:0,
    template:'<div></div>',
    replace: true,
    controller: 'TabCtrl',
    transclude: false,
    restrict: 'E',
    scope: false,
    compile: function (element, attrs){
      return function (parentScope, instanceEle){
        parentScope.$watch('type', function(val) {
          element.html('<div '+val+'></div>');
        });
      }
      $compile(parentScope);
    },
    link: function postLink(scope, iElement, iAttrs){}
  };
  return myObj;

});

The HTML is parsed properly, and the value for type is found in the controller JS.

so <tabcontent></tabcontent> is replaced with <div recipe></div> for example..

(that part does happen properly)

So I also have a directive for recipe:

tabsApp.directive('recipe', function(){

  var myObj = {
    priority:0,
    template:'<div>TESTING</div>',
    replace: true,
    controller: 'TabCtrl',
    transclude: false,
    restrict: 'E',
    scope: false,
    compile: function (element, attrs){
      return {
        pre: function preLink(scope, iElement, iAttrs, controller){},
        post: function postLink(scope, iElement, iAttrs, controller){}
      }
    },
    link: function postLink(scope, iElement, iAttrs){}
  };
  return myObj;

});

Which is obviously pretty simple, and just for testing. But the recipe directive is not being processed...

Whats going on here?

Upvotes: 11

Views: 8374

Answers (1)

bmleite
bmleite

Reputation: 26880

You need to change 2 things:

  1. The recipe directive must not be restricted to E (element). If you are generating the directive like <div recipe></div>, you must at least add A (attribute) to the restrict property on the directive configuration:

    app.directive('recipe', function() {
       return {
          restrict: 'E',
          ...
    
  2. You need to compile the HTML content of the tabcontent directive after the 'watch':

    app.directive('tabcontent', function($compile){
       return {    
       ...    
       link: function (scope, iElement, iAttrs) {
                scope.$watch('type', function(val) {
                   iElement.html('<div '+val+'></div>');           
                   $compile(iElement.contents())(scope);         
                 });
             }
       ...        
    

jsFiddle: http://jsfiddle.net/bmleite/n2BXp/

Upvotes: 19

Related Questions