Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass the scope to a directive templateUrl: function?

I have a directive that I'm calling with in a loop. Each item in the loop has a FieldTypeId attribute, and depending on the value of FieldTypeId, I want to swap out the URL of the template. I feel that this is a better and polymorphic approach rather than doing an ng-switch statement in the html.

<div ng-repeat="item in attributes">
  <div attribute-input></div>
</div>

Of course, the $scope isn't available in this directive:

editStudentAccountModule.directive('attributeInput', function () {
        return {
            restrict: "AE",
            templateUrl: function () { // 
               var attribute = $scope.attributes[$scope.$index];
               if (attribute.FieldTypeId == 1) {
                 return '../Templates/dropdown.html';
               } else if (attribute.FieldTypeId == 2) {
                 return '../Templates/radio.html';
               } // etc.
            }
        }
    });
like image 785
Adam Levitt Avatar asked Jun 02 '14 03:06

Adam Levitt


1 Answers

You would need to load the template within the link function in order to have access to the scope, before that you just have access to the template itself in either template or compile, check out the write up here: What are the benefits of a directive template function in Angularjs?

This is obvious if you've ever actually used the $compile service directly. When you call $compile on some DOM it returns the link function which you then call passing a scope along for it to execute on. So when you see it from that perspective it's sort of obvious that you won't have the scope until the compile has been called and the link function is returned and then called with the scope... it looks something like this:

$compile("<div ng-repeat='thing in things'></div>")({things:['thing1','thing2']});//Normally you would pass a scope object in here but it can really be whatever

Here's a bit of stab in the dark at your code:

editStudentAccountModule.directive('attributeInput', function () {
        return {
            restrict: "AE",
            scope:{info:"="},
            link: function(scope){
              var templateToUse = '../Templates/default.html';
              if (scope.info.FieldTypeId == 1) {
                templateToUse '../Templates/dropdown.html';
              } else if (scope.info.FieldTypeId == 2) {
                templateToUse '../Templates/radio.html';
              } // etc.
              scope.myTemplate = templateToUse;
            },
            template:"<div ng-include='myTemplate'></div>";
        }
    });



<div ng-repeat="item in attributes">
  <div attribute-input info="item"></div>
</div>
like image 98
shaunhusain Avatar answered Sep 25 '22 01:09

shaunhusain