2

I have this directive:

    gymApp.directive('ngListar', function() { 
      return { 
        templateUrl: function(elem, attr){
          console.log(attr.type);
          return 'js/directives/listar-'+attr.type+'.html';
        }
      }; 
    });

The idea is that when I call the directive a parameter is added that will determine which html file to call, so the html looks like this

    <tr ng-listar type="{{list.tipo}}"></tr>

But the log prints out {{list.tipo}} instead of the value inside of it. Is there a way I can pass the expression as a parameter?

sfletche
  • 47,248
  • 30
  • 103
  • 119
AskOcre
  • 115
  • 11
  • 3
    Have you tried ``? That is, without the braces. – kubuntu Feb 24 '16 at 20:33
  • Without the braces the console log just brings: list.tipo without the braces. – AskOcre Feb 24 '16 at 20:43
  • Please avoid using `ng-` as prefix as that is reserved for AngularJS built-in directives. Also avoid using `type` as a custom attribute as the browser already uses that attribute name. – georgeawg Feb 24 '16 at 22:26
  • Use the `ng-include` directive, see [AngularJS ng-include Directive API Reference](https://docs.angularjs.org/api/ng/directive/ngInclude). – georgeawg Feb 24 '16 at 22:59
  • Possible duplicate of [How to get evaluated attributes inside a custom directive](http://stackoverflow.com/questions/12371159/how-to-get-evaluated-attributes-inside-a-custom-directive) – James Lawruk Nov 29 '16 at 17:08

2 Answers2

1

The reason this doesn't work is described in the docs for the templateUrl (emphasis mine):

Because template loading is asynchronous the compiler will suspend compilation of directives on that element for later when the template has been resolved. In the meantime it will continue to compile and link sibling and parent elements as though this element had not contained any directives.

The variable binding that Angular does is a directive and therefore won't complete until after your directive is done loading its template.

As for a work-around, you might need to manually call $compile yourself instead of relying on templateUrl to do it for you. See the second note under $compile for that.

Borrowing some code from this answer, you can do the following in your directive if you use $templateRequest:

link: function(scope, element, attr){
   $templateRequest('js/directives/listar-' + attr.type + '.html').then(function(html){
      var template = angular.element(html);
      element.append(template);
      $compile(template)(scope);
   });
};

$templateCache and $http.get should also be options with very similar code to the above. That should get around the issue of the value not being interpolated yet.

Community
  • 1
  • 1
Matthew Green
  • 10,161
  • 4
  • 36
  • 54
0

Instead of getting in attr, Print your scope variable.

app.directive("insertAfter", function(){
    return {
        scope: {
            content: "@",
            type: "@"
        }, 
        link: function(scope, element, attrs){
            console.log(scope.type);
            element.after(scope.content);
        }
    }
  });
Pankaj Chauhan
  • 346
  • 3
  • 8