Angular.js Directive with dynamic templateURL

Asked

Viewed 332 times

2

create.directive('renderInputs', [ function(){
    return {
        restrict: 'E',
        scope: true,
        templateUrl: function(elem, attrs) {
            alert(attrs.type);
            return '../templates/inputs/type-' + attrs.type + '.html';
        }
    }
}]);

<render-inputs  type="{{ p.input.type }}"></render-inputs>
  • Error: Error: [$compile:tpload] Failed to load template: ../templates/inputs/type-{{ p.input.type }}.html (HTTP status: 404 Not Found)

I’m having trouble loading a template dynamically. Man alert is returning {{ p.input.type }}, in reality was to return a type with these values: radio, checkbox, etc. for example: '../templates/inputs/type-radio.html'

1 answer

1

This is happening because the value is being passed literally, without evaluation in the scope context.

In theory you can use $scope.eval(attrs.type) to evaluate the expression: however this is not a very elegant solution.

Use a template with ng-include, at the same time that forces the evaluation of the expression {{ p.input.type }} via the scope marker @. Functional example to follow:

var create = angular.module("create", []);

create.controller("testController", function ($scope) {});

create.directive('renderInputs', function() {
       return {
           restrict: 'E',
           scope: { type: "@type" },
           link: function(scope, element, attrs) {
           
               scope.contentUrl= function() {
                    return 'type-' + scope.type + '.html';
               }
           },
           template: '<div ng-include="contentUrl()"></div>'
       }
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script type="text/ng-template" id="type-radio.html">
    <input type='radio' />
</script>

<script type="text/ng-template" id="type-text.html">
    <input type='text' />
</script>

<body ng-app='create'>
    <div ng-controller="testController">
         <render-inputs type='radio'></render-inputs>
         <render-inputs type='text'></render-inputs>
    </div>
</body>

This answer is a adaptation of this post in the original OS.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.