0

I am attempting to set the template of a directive dynamically using tips from this link

Here is the code for my directive.

var app = angular.module('sck-table', [

]).directive('tableInput', function(){
   return {
       restrict: 'E',
        scope: {
            field:'=field',
        },
        template:'<ng-include src="getTemplateUrl()"/>',
        controller: function($scope){
        $scope.count = 0;
            $scope.getTemplateUrl = function() {
               $scope.count++;
                console.log('this has been ran: '+$scope.count);
                console.log($scope.field.type);
                if($scope.field.type === 'select'){
                    return 'table/views/table-input-select.html';
                }
                if($scope.field.type === 'number'){
                    return 'table/views/table-input-number.html';
                }
            };
        }
    };
});

I am using this directive inside of an ng-repeat directive that runs 2 times.(test.fields has a length of 2)

<td ng-repeat="field in test.fields">
    <table-input field="field" ></table-input>
</td>

I expect the function getTemplateUrl() to run twice. Once for each item in test.fields.

However when I run this... the console logs 28 times.enter image description here

I seem to get the desired results... meaning the template is successfully injected into the page, but I was wondering if anyone could tell me why the getTemplateUrl() function is called so many times, and if I can do anything to prevent this.

Thanks in advance.

  • how many rows do you have in your table? – Michael Kang Nov 02 '15 at 04:13
  • only one row... just testing for now – richardnixonthethird Nov 02 '15 at 04:14
  • Function calls in templates are evaluated on each digest cycle. – Phil Nov 02 '15 at 04:14
  • Phil is correct. To avoid this, you should assign the result of getTemplateUrl() to a $scope model property inside of your controller constructor, then bind to the model property in your template. – Michael Kang Nov 02 '15 at 04:16
  • 1
    Possible duplicate of [Angular.js directive dynamic templateURL](http://stackoverflow.com/questions/21835471/angular-js-directive-dynamic-templateurl) but look to the [most upvoted answer](http://stackoverflow.com/a/23999356/283366) instead of the accepted one – Phil Nov 02 '15 at 04:20
  • Can't you just call a function instead of having `ng-include` and a function call. You can use your `field` attribute or smth like that for each of the directive. Doesn't look pretty anyway(( – Said Kholov Nov 02 '15 at 04:21
  • Yeah, take a look at the link @Phil provided – Said Kholov Nov 02 '15 at 04:25
  • The most upvoted answer requires passing in the url through the attributes. This is not what I wanted to do. – richardnixonthethird Nov 02 '15 at 04:28

1 Answers1

0

Thanks to the comments left on my question and the linked posts, I have come up with this solution.

var app = angular.module('sck-table', [

]).directive('tableInput', function(){
    var contentUrl;
    return {
        restrict: 'E',
        scope: {
            field:'=field',
        },
        link: function(scope,element,attrs){
            scope.contentUrl = 'table/views/table-input-'+scope.field.type+'.html';
        },
        template: '<ng-include src="contentUrl"/>'
    };
});