2

First of all, the way i am doing may not be correct. But i will explain the problem:

1) I am creating directive called as < firstDirective >

2) when the clicks on a button in the first directive, then I am trying to insert the second directive dynamically at runtime

As follows:

<!DOCTYPE html>
<html>
<script src="lib/angular/angular.js"></script>
<body ng-app="myApp">

<first-directive></first-directive>

<script>
var app = angular.module("myApp", []);
app.directive("firstDirective", function() {
    return {
       template : '<h1>This is first directive!</h1> <br / ><br / ><button type="button" ng-click="firstCtrl()">Click Me to second directive!</button> <div id="insertSecond"></div> ',
        controller: function ($scope) {
              $scope.firstCtrl = function($scope) {
                    angular.element(document.querySelector('#insertSecond')).append('<second-directive></second-directive>');                  
              } 
        }
    }
});        

app.directive("secondDirective", function() {
    return {
       template : '<h1>This is second directive!</h1> <br / ><br / >',
        controller: function ($scope) {

        }
    }
});        


 </body>
 </html> 

But it is not working, i mean, it is inserting the "< second-directive > < / second-directive >" text but not the content as per the directive above.

I am new to angular js, I think we can do this in a different way or my approach itself is not correct. But all i want to insert the second directive dynamically.

EDIT:: I got the solution for this, thanks to the George Lee:

Solution is we have to compile as follows, but didn’t pass scope object to the function:

<!DOCTYPE html>
<html>
<script src="lib/angular/angular.js"></script>
<body ng-app="myApp">

<first-directive></first-directive>

<script>
var app = angular.module("myApp", []);
app.directive("firstDirective", function($compile) {
    return {
       templateUrl : '<h1>This is first directive!</h1> <br / ><br / ><button type="button" ng-click="firstCtrl()">Click Me to second directive!</button> <div id="insertSecond"></div> ',
        controller: function ($scope) {
              $scope.firstCtrl = function() {
                    var ele = $compile('<second-directive></second-directive>')($scope);
                    angular.element(document.querySelector('#insertSecond')).append(ele);                  
              } 
        }
    }
});        

app.directive("firstDirective", function() {
    return {
       templateUrl : '<h1>This is second directive!</h1> <br / ><br / >',
        controller: function ($scope) {

        }
    }
});

Also, this link , gives very good explanation of how to dynamically compile and inject the templates.

2 Answers 2

2

You can use the $compile service in Angular, make sure you include it in the dependency injection.

app.directive("firstDirective", ['$compile', function($compile) {
...
controller: function ($scope) {
    $scope.firstCtrl = function() {
         var ele = $compile('<second-directive></second-directive>')($scope);
         angular.element(document.querySelector('#insertSecond')).append(ele);                  
    } 
}
Sign up to request clarification or add additional context in comments.

5 Comments

I done as you specified above, it is throwing error saying like, " Error: [ng:areq] Argument 'scope' is required ", check this link : docs.angularjs.org/error/ng/areq?p0=scope&p1=required
Try removing $scope function argument from firstCtrl function. So... $scope.firstCtrl = function() { ...
Great :) thanks buddy i got it. After removing the $scope element from the firstctrl function. But one more thing Lee, we didnot have to inject $compile as you said, we can simply use, like this from Angular JS Documentation: " app.directive("firstDirective", function($compile) { " In this way, it is working fine. I am rating you up.
That is dependency injection as well and is implicit on the function argument name. Your dependency injection will break if you minify your js file and it renames the parameter. It is "best practice" to define as how I have in my answer, then it doesn't matter what the argument name is.
Yes, you are right @George Lee, it is working with the compile injection also.
0

There is one more problem instead of templateUrl, template should be there

    <!DOCTYPE html>
     <html>
        <script data-require="[email protected]" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js" data-semver="1.0.8"></script>

         <first-directive></first-directive>

     <script>
      var app = angular.module("myApp", []);
          app.directive("firstDirective", function($compile) {
              return {
              template : '<h1>This is first directive!</h1> <br / ><br / ><button type="button" ng-click="firstCtrl()">Click Me to second directive!</button> <div id="insertSecond"></div> ',
              controller: function ($scope) {
              $scope.firstCtrl = function() {
                var ele = $compile('<second-directive></second-directive>')($scope);
                angular.element(document.querySelector('#insertSecond')).append(ele);
             }
         },
          restrict: "EAC"

   }

});

          app.directive("secondDirective", function() {
             return {
             template : '<h1>This is second directive!</h1> <br / ><br / >',
             controller: function ($scope) {

       },
             restrict: "EAC"
    }
  });
     </script>
   </body>
 </html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.