SunnyShah
SunnyShah

Reputation: 30517

How to make AngularJS compile the code generated by directive?

Please help me on, How can we make AngularJS compile the code generated by directive ?

You can even find the same code here, http://jsbin.com/obuqip/4/edit

HTML

<div ng-controller="myController">
    {{names[0]}} {{names[1]}}
    <br/> <hello-world my-username="names[0]"></hello-world>
    <br/> <hello-world my-username="names[1]"></hello-world>
    <br/><button ng-click="clicked()">Click Me</button>
</div>

Javascript

var components= angular.module('components', []);
components.controller("myController",
    function ($scope) {
        var counter = 1;
        $scope.names = ["Number0","lorem","Epsum"];
        $scope.clicked = function() {
            $scope.names[0] = "Number" + counter++;
        };
    }
);

// **Here is the directive code**
components.directive('helloWorld', function() {
    var directiveObj =  {
        link:function(scope, element, attrs) {
            var strTemplate, strUserT = attrs.myUsername || "";
            console.log(strUserT);
            if(strUserT) {
                strTemplate = "<DIV> Hello" + "{{" + strUserT +"}} </DIV>" ;
            } else {
                strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ;
            }
            element.replaceWith(strTemplate);
        },
        restrict: 'E'
    };
    return directiveObj;
});

Upvotes: 8

Views: 19670

Answers (3)

Liviu T.
Liviu T.

Reputation: 23664

You need to create an angular element from the template and use the $compile service

jsBin

components.directive('helloWorld', ['$compile', function(compile) {
    var directiveObj =  {
        link: function(scope, element, attrs) {
            var strTemplate, strUserT = attrs.myUsername || "";
            console.log(strUserT);
            if (strUserT) {
                strTemplate = "<DIV> Hello" + "{{" + strUserT +"}} </DIV>" ;
            } else {
                strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ;
            }

            var e = angular.element(strTemplate);
            compile(e.contents())(scope);
            element.replaceWith(e);
        },
        template: function() {
            console.log(args);
            return "Hello";
        },
        restrict: 'E'
    };
    return directiveObj;
}]);

Upvotes: 9

Mark Rajcok
Mark Rajcok

Reputation: 364727

Here's a version that doesn't use a compile function nor a link function:

myApp.directive('helloWorld', function () {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      myUsername: '@'
    },
    template: '<span><div ng-show="myUsername">Hello {{myUsername}}</div>'
    + '<div ng-hide="myUsername">Sorry, No user to greet!</div></span>',
  };
});

Note that the template is wrapped in a <span> because a template needs to have one root element. (Without the <span>, it would have two <div> root elements.)

The HTML needs to be modified slightly, to interpolate:

<hello-world my-username="{{names[0]}}"></hello-world>

Fiddle.

Upvotes: 14

SunnyShah
SunnyShah

Reputation: 30517

Code: http://jsbin.com/obuqip/9/edit

components.directive('helloWorld', function() {
    var directiveObj =  {
        compile:function(element, attrs) {
            var strTemplate, strUserT = attrs.myUsername || "";
            console.log(strUserT);
            if(strUserT) {
                strTemplate = "<DIV> Hello " + "{{" + strUserT +"}} </DIV>" ;
            } else {
                strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ;
            }
            element.replaceWith(strTemplate);
        },
        restrict: 'E'
    };
    return directiveObj;
});

Explanation: The same code should be used in compile function rather than linking function. AngularJS does compile the generated content of compile function.

Upvotes: 10

Related Questions