0

I'd like to have a directive with multiple templates as in this SO

When using compile in a directive as in this jsfiddle the the ng-include uses the external controller and the and the internal controller is not available to the scope of the template

example

function someDirective(){
return {
scope:{
  ...
},

compile: function(element, attrs) {
  var type = "extended"; //default
  if(typeof attrs.type !== 'undefined')
    type = attrs.type;
  element.append('<div ng-include="\'myproj/views/templates/group/groups-' + type + '.html\'"></div>');
},
//templateUrl: 'myproj/views/templates/group/groups-sideMenu.html',
controller:function($scope, $attrs, $rootScope, UtilsSrvc){
  // ... the template won't use this controller  
 }
 }
 }

how to fix this problem?

EDIT

After some headbang something got clearer In this fiddle (by Alessandro Cifani) the script works either for Angular 1.0, Angular 1.1 and Angular 1.2

The problems start when trying to isolate the scope: this fiddle only works with Angular <= 1.1, with Angular >= 1.2 is not working

Things change when an empty 'templateUrl' is added as shown in this fiddle: it starts to be compliant to all versions

???????????????

Community
  • 1
  • 1
davidetrapani
  • 461
  • 1
  • 6
  • 14

1 Answers1

1

I would use a different approach:

1) yoy may use the $compile service

2) you should avoid to use ng-include in favor of custom directives.

Following an example of what I'm saying:

(function () {
  'use strict';

  angular.module('myApp', [])

  .directive('user',
    function user($compile, $window) {
      return {
        scope: {
          role: '@',
          name: '@'
        },
        restrict: 'EA',

        link: function link(scope, elem) {

          var roles = {
            SUPERADMIN: '<button ng-click="doSomething()" class="btn">Do something</button>',
            STUDENT: '<div class="alert alert-success">You are a student</div>',
            OTHER: '<div>Guest users have no options</div>'
          };

          // Create HTML elements in according with the role (SUPERADMIN, STUDENT, OTHER)
          var role = roles[scope.role] || roles.OTHER;
          var html = '<div><h2>' + scope.name + '</h2>' + role + '</div>';

          // Step 1: parse HTML into DOM element
          var template = angular.element(html);
          //console.log (html);

          // Step 2: compile the template
          var linkFn = $compile(template);
          //console.log (linkFn);

          // Step 3: link the compiled template with the scope.
          var element = linkFn(scope);
          console.log (element[0]);

          // Step 4: Append to DOM (optional)
          elem.append(element);

          scope.doSomething = function doSomething() {
            $window.alert('doSomething');
          };

        }
      };
    }
  );

})();

USAGE:

<user name="fabio" role="SUPERADMIN"></user>
<user name="paolo" role="STUDENT"></user>
<user name="marco"></user>

NOTE: in the previous example you could replace my "SUPERADMIN", "STUDENT" and "OTHER" templates with your own custom directives, ie: , ,

and here a JSBin: https://jsbin.com/mumahobuwu/edit?html,js,output

fabio_biondi
  • 969
  • 10
  • 9