Greg
Greg

Reputation: 7922

Any way to dynamically load angular directives?

Here's a short fiddle:

http://jsfiddle.net/aSg9D/

Basically, neither <div data-foo-{{letterA}}></div> nor <div data-ng:model="foo-{{letterB}}"></div> are interpolated.

I'm looking for a way to dynamically load one of several inline templates.

Pardon me if this has already been asked before, but I searched and couldn't find it.


I believe Radim Köhler has the correct answer. Just before it was posted, I hacked together something to load directives from another directive like this:

angular.module('myApp', []).directive('loadTmpl', function($compile) {
    return {
        restrict: 'A',
        replace: true,
        link: function($scope, $element, $attr) {
            $element.html("<div data-card-"+$attr.loadTmpl+"></div>");
            $compile($element.contents())($scope);
        }
    };
});

And:

<div data-load-tmpl="{{directiveName}}"></div>

I think that's the minimalist approach, but there's probably something wrong with it, so just look at the answer below.

Upvotes: 2

Views: 205

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123851

Let's adjust it this way (the udpated fiddle). The view:

<div my-selector name="letterA"></div>
<div my-selector name="letterB"></div>

the controller:

function myCtrl($scope) {
    $scope.letterA = 'bar';
    $scope.letterB = 'baz';
}

And here is new directive mySelector, containing the selector

.directive('mySelector', 
  [       '$templateCache','$compile', 
  function($templateCache , $compile) {
    return {
      scope: {
        name: '='
      },
      replace: true,   
      template: '',            
      link: function (scope, elm, attrs) {

        scope.buildView = function (name) {
            var tmpl = $templateCache.get("dir-foo-" + name);
            var view = $compile(tmpl)(scope);
            elm.append(view);
        }
      },
      controller: ['$scope', function (scope) {
        scope.$watch('name', function (name) {
            scope.buildView(name);
        });
      }],          
    };
}])
.run(['$templateCache', function ($templateCache) {
    $templateCache.put("dir-foo-bar", '<div data-foo-bar></div>');
    $templateCache.put("dir-foo-baz", '<div data-foo-baz></div>');
}])

In case you like it, all credits goes to Render a directive inside another directive (within repeater template) and AngularJS - Directive template dynamic, if you don't, blame me.

Upvotes: 1

Related Questions