Cody Jacques
Cody Jacques

Reputation: 524

adding directives to a page using ng-repeat

I'm trying to add directives to a page using ng-repeat. Basically I want to do something like:

<{{ currentDirective.directiveName }} ng-repeat="currentDirective in directiveList" />

Here's an example of what I'm trying to do in context.

http://jsfiddle.net/s9hf758w/

Upvotes: 2

Views: 904

Answers (2)

Jon Hieb
Jon Hieb

Reputation: 780

I forked the fiddle and worked out a solution using a directive I called bind-compiled-html:

http://jsfiddle.net/hiebj/Lbusqf26/

Directive code:

function bindCompiledHtml($compile) {
    return {
        restrict: 'A',
        link: function($scope, $element, $attrs) {
            var html = $scope.$eval($attrs.bindCompiledHtml),
                toCompile = angular.element(html);
            $element.append($compile(toCompile)($scope));
        }
    };
}

Usage:

<div ng-repeat="directive in directiveHtmlList"
    bind-compiled-html="directive.directiveHtml">
</div>

This solution doesn't require $sanitize or $sce.trustAsHtml and keeps the messy DOM details out of your controller. I also included a version called bind-directive in case you really need to iterate over a list of directive names, but bind-compiled-html is more flexible.

You could successfully insert the HTML by using $sce.trustAsHtml along with ng-bind-html, but if you do that, Angular won't notice that you've added directives to your DOM. You have to tell it to $compile the new DOM elements after ng-repeat runs.

This will get you close to what you are looking for, but unfortunately you will not be able to use ng-repeat directly on your custom directive. You will have to use it on a wrapping element - ng-repeat is an attribute-only directive. The replace property of directives is deprecated, and besides it would cause major problems by destroying your original ng-repeat. Using the bind-compiled-html solution, you will end up with:

<div class="ng-scope ng-binding"
    ng-repeat="directive in directiveHtmlList"
    bind-compiled-html="directive.directiveHtml">
    <first-directive></first-directive>
</div>
<div class="ng-scope ng-binding"
    ng-repeat="directive in directiveHtmlList"
    bind-compiled-html="directive.directiveHtml">
    <second-directive></second-directive>
</div>

For more, check out the Angular docs on ng-bind-html (the inspiration for bind-compiled-html) and $compile.

Upvotes: 1

Dominique Canlas
Dominique Canlas

Reputation: 149

Why are you trying to add directives this way? Based on your example, the directives that you have return something different? Not sure what exactly you are trying to accomplish but the proper way to do it would be to have

<div my-directive ng-repeat="i in item" />

and the directive will have logic in it's controller or link functions

Upvotes: 1

Related Questions