1

TL;DR: Is there a way to dynamically set a directive based on a parameter value? Something similar to ng-class for setting css elements, but a way to set the directive based on the value in the scope. I would have the value in the scope so I could call:

<div class="data.directiveType"></div>

When

data.directiveType = "my-directive"

the div would become

<div class="my-directive"></div>

and myDirective would be invoked?

Detailed Question:

What I am trying to do is allow the user to add elements to the web application and I wanted the directive for each element to be added based on what the user clicks.

I have the following Directives:

app.directive("mySuperman", function(){
    //directive logic
});

app.directive("myBatman", function(){
    //directive logic
});

app.directive("myWonderWoman", function(){
    //directive logic
});

I have the following controller

app.controller("ParentCtrl", function($scope){
    $scope.superHeros = [];

    var superman = {directiveType: "my-superman"};
    var batman = {directiveType: "my-batman"};
    var wonderWoman = {directiveType: "my-wonder-woman"}

    $scope.addBatman = function()
    {
        var batmanInstance = {}
        angular.copy(batman, batmanInstance);
        $scope.superHeros.push(batmanInstance);
    }

    $scope.addSuperman = function()
    {
        var supermanInstance = {}
        angular.copy(superman, supermanInstance);
        $scope.superHeros.push(supermanInstance);
    }

    $scope.addWonderWoman = function()
    {
        var wonderwomanInstance = {}
        angular.copy(wonderWoman, wonderwomanInstance);
        $scope.superHeros.push(wonderwomanInstance);
    }

});

In the index.html I have

<body ng-controller="ParentCtrl>
    <a ng-click="addBatman()">Add Batman</a>
    <a ng-click="addSuperman()">Add Superman</a>
    <a ng-click="addWonderWoman()">Add WonderWoman</a>

    <div ng-repeat="hero in superHeros">
        <!-- The following doesn't work, but it is the functionality I am trying to achieve -->
        <div class={{hero.directiveType}}></div>
    <div>
</body>

The other way I thought of doing this was just using ng-include in the ng-repeat and adding the template url to the hero object instead of the directive type, but I was hoping there was a cleaner way that I could make better use of the data binding and not have to call ng-include just to call another directive.

1 Answer 1

3

You can create a directive that takes the directive to add as a parameter, adds it to the element and compiles it. Then use it like this:

<div ng-repeat="hero in superHeros">
  <div add-directive="hero.directiveType"></div>
</div>

Here is a basic example:

app.directive('addDirective', function($parse, $compile) {

  return {
    compile: function compile(tElement, tAttrs) {

      var directiveGetter = $parse(tAttrs.addDirective);

      return function postLink(scope, element) {

        element.removeAttr('add-directive');

        var directive = directiveGetter(scope);
        element.attr(directive, '');

        $compile(element)(scope);
      };
    }
  };
});

Demo: http://plnkr.co/edit/N4WMe8IEg3LVxYkdjgAu?p=preview

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.