22

I am trying to load a HTML template when a link is clicked. I have made a directive that contains templateUrl which loads a HTML file. I am calling a function when a link is clicked that appends a div with our custom directive "myCustomer" to a div already in index.html. whatever i have done so far is shown below, but it doesn't work.

index.html

    <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example - example-example12-production</title>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
  <script src="script.js"></script>
</head>
<body ng-app="docsTemplateUrlDirective">
  <div ng-controller="Controller">
  <a href="#" ng-click="showdiv()">show</a>
  <div id="d"></div>
</div>
</body>
</html>

script.js

(function(angular) {
  'use strict';
angular.module('docsTemplateUrlDirective', [])
  .controller('Controller', ['$scope', function($scope) {

    $scope.showdiv = function(){
      $("#d").append("<div my-Customer></div>");
    };
  }])
  .directive('myCustomer', function() {
    return {
      templateUrl: 'my-customer.html'
    };
  });
})(window.angular);

my-customer.html

<p>DIV CONTENT</p>

Here is the link i was testing this code here

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Vikram Singh Jadon
  • 1,007
  • 1
  • 10
  • 23

4 Answers4

37

This is because the angular doesn't bind the directives if you append content like this,

you need to $compile service to do this and this will bind the directives against your $scope

so controller like,

.controller('Controller', ['$scope', '$compile', function($scope, $compile)     {

    $scope.showdiv = function(){
      var compiledeHTML = $compile("<div my-Customer></div>")($scope);
      $("#d").append(compiledeHTML);
    };

}])

here is the DEMO


OR good to do like this,

use ng-if to create or removing element from html,

try this code

Controller,

....
$scope.anableCustomerDirective = false;
$scope.showdiv = function(){
  $scope.anableCustomerDirective = true;
};

HTML

<body ng-app="docsTemplateUrlDirective">
  <div ng-controller="Controller">
      <a href="#" ng-click="showdiv()">show</a>
      <div id="d">
          <div my-Customer ng-if='anableCustomerDirective'></div>
      </div>
 </div>
</body>

Suggestion

if your main intention is to place a html content after the click, then you can use ng-include here and it will much cleaner and no need of a another directive.

<div id="d">        
    <div ng-include="templateURL"></div>
 </div>

 $scope.showdiv = function(){
      $scope.templateURL = 'my-customer.html';
 };

find the DEMO

Kalhan.Toress
  • 21,683
  • 8
  • 68
  • 92
  • 1
    Its like I asked and you made the changes in your code..Cool answer..Which is explaining all the possibility with what is wrong and which is right :p +1 from me dude. Cheers :) – Pankaj Parkar Jun 21 '15 at 17:58
  • This is working very nice, but what if I created a form dynamically and want to bind values with different variables?? How to get the index to dynamically added form? – Prasanna Sep 27 '17 at 11:03
8

Seems like directive is only meant to load template from it.I'd suggest you to use ng-include directive then

Markup

<a href="#" ng-click="showDiv=true">show</a>
<div id="d"></div>
<div ng-include="showDiv ? 'my-customer.html': ''">
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
1

The most common way is to use $compile. More info: Dynamically add directive in AngularJS

Then your controller may look like this:

angular.module('docsTemplateUrlDirective', [])
  .controller('Controller', ['$scope', '$compile', function($scope, $compile) {

    $scope.showdiv = function(){
        var el = $compile( "<div my-customer></div>" )( $scope );
        $('#d').append( el );
    };
  }]);

Note that the directive invokation should look like this: <div my-customer>, not <div my-Customer></div> as you have in your code.

Community
  • 1
  • 1
Thomas Weglinski
  • 1,094
  • 1
  • 10
  • 21
  • @pankajparkar Thanks for the tip, but I have just answered the question what was wrong in Vikram code. – Thomas Weglinski Jun 21 '15 at 17:54
  • you should have answer in correct way of doing it..not to get OP going in wrong way..that can lead him to may got in different issue ..Though I didn't downvoted :p – Pankaj Parkar Jun 21 '15 at 17:56
0

when you do it manually with append you actually do not run $apply or $digest so the directive is not run, can you try to do it with ng-show or ng-if ... e.g

  <body ng-app="docsTemplateUrlDirective">
  <div ng-controller="Controller">
  <a href="#" ng-click="showdiv = true">show</a>
   <div my-customer ng-if="showdiv"></div>
  <div id="d"></div>
</div>
</body>

this way angular runs the $apply and the directive will be rendered.

Jony-Y
  • 1,579
  • 1
  • 13
  • 30