Search code examples
angularjstemplatesangularjs-ng-clickangularjs-compile

In AngularJS, how do I generate a piece of content from template and insert it in the DOM when a link is clicked


I have a number of links on the page, dynamically generated like so:

<a href="#" class="more-info-item" ng-click="showStats(item, $event)">
   More information
</a>

I also have a simple custom template that should show an item's name:

<script type="text/ng-template" id="iteminfo.html">
  <div class="item-name">
    {{item.name}}
  </div>
</script>

What I would like to do is: when the link is clicked, to dynamically compile the template, and insert it in the DOM right after the link. I tried using $compile within showStats method to compile the template, but I got an error that $compile wasn't found. How would I go about doing this (and also provide item as part of the scope for the newly generated template)?


Solution

  • Here is a solution using a custom directive which injects the item dynamically using ng-if:

    View Solution with Plunker

    html:

    <script type="text/ng-template" id="iteminfo.html">
        <div class="item-name" ng-if="item.visible">
                {{item.name}}
        </div>
    </script>
    <div ng-repeat="item in items" >
        <a href="#" class="more-info-item" more-info="item" ng-click="item.visible =!item.visible">
              More information
        </a>
    </div>
    

    script:

            angular.module('app', [])
            .controller('ctrl', function($scope)  {
                    $scope.items = [{name:'apples', visible:false},{name:'pears', visible:false},{name:'oranges', visible:false}];
            })
            .directive('moreInfo', function($compile,$templateCache) {
                    return {
                        restrict: 'A',
                        scope: '=',
                        link: function(scope, element, attr) {
    
                                var itemInfo = angular.element($templateCache.get('iteminfo.html'));
                                var lfn = $compile(itemInfo);
                                element.parent().append(itemInfo);
                                lfn(scope);
                        }
                };
      });