Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.js directive dynamic templateURL

People also ask

What is templateUrl in AngularJS?

templateUrl can also be a function which returns the URL of an HTML template to be loaded and used for the directive. AngularJS will call the templateUrl function with two parameters: the element that the directive was called on, and an attr object associated with that element.

What is restrict in AngularJS directive?

Directives are a special type of AngularJS component used to extend the functionality of an HTML element or create new features with a rich behavior that is not available using pure HTML. AngularJS includes pre-built directives like ngBind , ngModel , and ngClass .

What is link in AngularJS directive?

AngularJS Directive's link key defines link function for the directive. Precisely, using link function, we can define directive's API & functions that can then be used by directive to preform some business logic. The link function is also responsible for registering DOM listeners as well as updating the DOM.


emanuel.directive('hymn', function() {
   return {
       restrict: 'E',
       link: function(scope, element, attrs) {
           // some ode
       },
       templateUrl: function(elem,attrs) {
           return attrs.templateUrl || 'some/path/default.html'
       }
   }
});

So you can provide templateUrl via markup

<hymn template-url="contentUrl"><hymn>

Now you just take a care that property contentUrl populates with dynamically generated path.


You can use ng-include directive.

Try something like this:

emanuel.directive('hymn', function() {
   return {
       restrict: 'E',
       link: function(scope, element, attrs) {
           scope.getContentUrl = function() {
                return 'content/excerpts/hymn-' + attrs.ver + '.html';
           }
       },
       template: '<div ng-include="getContentUrl()"></div>'
   }
});

UPD. for watching ver attribute

emanuel.directive('hymn', function() {
   return {
       restrict: 'E',
       link: function(scope, element, attrs) {
           scope.contentUrl = 'content/excerpts/hymn-' + attrs.ver + '.html';
           attrs.$observe("ver",function(v){
               scope.contentUrl = 'content/excerpts/hymn-' + v + '.html';
           });
       },
       template: '<div ng-include="contentUrl"></div>'
   }
});

Thanks to @pgregory, I could resolve my problem using this directive for inline editing

.directive("superEdit", function($compile){
    return{
        link: function(scope, element, attrs){
            var colName = attrs["superEdit"];
            alert(colName);

            scope.getContentUrl = function() {
                if (colName == 'Something') {
                    return 'app/correction/templates/lov-edit.html';
                }else {
                    return 'app/correction/templates/simple-edit.html';
                }
            }

            var template = '<div ng-include="getContentUrl()"></div>';

            var linkFn = $compile(template);
            var content = linkFn(scope);
            element.append(content);
        }
    }
})

You don't need custom directive here. Just use ng-include src attribute. It's compiled so you can put code inside. See plunker with solution for your issue.

<div ng-repeat="week in [1,2]">
  <div ng-repeat="day in ['monday', 'tuesday']">
    <ng-include src="'content/before-'+ week + '-' + day + '.html'"></ng-include>
  </div>
</div>

I had the same problem and I solved in a slightly different way from the others. I am using angular 1.4.4.

In my case, I have a shell template that creates a CSS Bootstrap panel:

<div class="class-container panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">{{title}} </h3>
    </div>
    <div class="panel-body">
        <sp-panel-body panelbodytpl="{{panelbodytpl}}"></sp-panel-body>
    </div>
</div>

I want to include panel body templates depending on the route.

    angular.module('MyApp')
    .directive('spPanelBody', ['$compile', function($compile){
        return {
            restrict        : 'E',
            scope : true,
            link: function (scope, element, attrs) {
                scope.data = angular.fromJson(scope.data);
                element.append($compile('<ng-include src="\'' + scope.panelbodytpl + '\'"></ng-include>')(scope));
            }
        }
    }]);

I then have the following template included when the route is #/students:

<div class="students-wrapper">
    <div ng-controller="StudentsIndexController as studentCtrl" class="row">
        <div ng-repeat="student in studentCtrl.students" class="col-sm-6 col-md-4 col-lg-3">
            <sp-panel 
            title="{{student.firstName}} {{student.middleName}} {{student.lastName}}"
            panelbodytpl="{{'/student/panel-body.html'}}"
            data="{{student}}"
            ></sp-panel>
        </div>
    </div>
</div>

The panel-body.html template as follows:

Date of Birth: {{data.dob * 1000 | date : 'dd MMM yyyy'}}

Sample data in the case someone wants to have a go:

var student = {
    'id'            : 1,
    'firstName'     : 'John',
    'middleName'    : '',
    'lastName'      : 'Smith',
    'dob'           : 1130799600,
    'current-class' : 5
}