0

I knwo that are many relevant posts about how creating dynamic directive mapping in angular but I cannot find anything similar in my case. As the description suggests I am trying to make a dynamic directive where depending the value of an object attribute the html is changed. I simplified my problem to this case:

I have a list of object "Widget" which has an attribute name 'type'. I want depending on the type attribute of this list to render html depending on the attribute. To be more specific the Widget.type can have 3 values for example: widget1,widget2 . So in my case I want the directive to return the file widget*.html. (widget1.html for widget type "widget1" etc). Though I pass the argument to the directive using attributes, the value is not evaluated and the string widget.type is return.

Can you help me? Thx in advance.

app.js file:

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

app.controller("myCtrl", function($scope) {
   function Widget(type){
     this.type=type;
    }

    $scope.widgets=[];

    $scope.widgets.push(new Widget('widget1'),new Widget('widget2'),new Widget('widget3'));



});

app.directive('widget', function() {
    return {
        restrict: 'E',
        scope: {
            obj: '='
        },
        templateUrl: function(element,attr){
            //console.log(attr);
            console.log(attr.obj);
            return attr.obj+'.html';
        }
    }

});

index.html file:

<!DOCTYPE html>
<html ng-app="MainCtrl">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>

    <!-- css  -->
    <link rel="stylesheet" href="style.css" />

    <!-- utilities  -->
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>

   <!--  angular module file -->
    <script src="script.js"></script>



  </head>

  <body  ng-controller="myCtrl">

                <div  ng-repeat="widget in widgets">
                  {{widget.type}}

                    <widget obj='widget.type'   ></widget>
                </div>

    </body>

widget1.html file:

<div class="widget">
    widget1:{{widget.type}}
</div>

widget2.html,widget3.html are the same

Notice the console output in the directive.

I created a plunker so it's easier to notice the problem:http://plnkr.co/edit/ulBSQQrqpSV9g3BNGRhO?p=preview

2
  • Console error: Error: [$compile:tpload] Failed to load template: widget.type.html (HTTP status: 404 Not Found). You don't have that html file, do you? Commented Feb 22, 2016 at 19:12
  • @matmo widget.type.html shouldn't be like this. The expression widget.type should evaluate to the according type Commented Feb 22, 2016 at 19:44

1 Answer 1

1

First example with your directive: http://plnkr.co/edit/XAXy5RGLnvUZIoRj5xAs?p=preview

Secone example without your directive:

<div  ng-repeat="widget in widgets">
   <!--{{widget.type}}-->
   <div ng-include="widget.template"></div> 
</div>

Note: additional property in your Widget-object. Easier to handle.

First one is not as beautiful as the example without the directive, becaue your scope-variable of the directive has to be the same as the variable in your templates ('widget'). I like the second example much more.

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

2 Comments

Though it's a great workaround and pretty straightforward , is there any way to make it work by my way? In my case the problem is simple, but what about a more complex one where more calculations must be done? I can't think any specific example but I wanted to pass an 'argument' to the directive in the first place...
It's still a argument, but you use 'widget' in your template e.g. in widget.html you use {{widget.type}}. So your attribute of the directive has to be named also 'widget', but it's still an argument. And the first example should be the one which is your way or do I miss something? If not, mark as solution. Calculation inside the directive? I don't know exactly whats your point of interest, but this would be helpful: weblogs.asp.net/dwahlin/…

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.