Uday Sawant
Uday Sawant

Reputation: 5798

Angular directives - How to select template based on attribute values?

I am developing a widget where I want to render some messages/text one after another. I want to change the template of the message based on the type of message.

my current directive setup is as follows

directive('cusMsgText', function(){
  return {
     restrict: 'E',
     template:function(elements, attrs){
        return '<div></div>';
     },
     link: function($scope, iElm, iAttrs, controller) {
        //add children to iElm based on msg values in $scope
     }
  };
});

The directive is used as follows

<div ng-repeat="(key, value) in chatUser.msg">  
    <data-cus-msg-text msg="value.type"></data-cus-msg-text>  
</div>

Now my question are -:

  1. Is it possible to return one of multiple strings (templates) from template function itself based on the actual value of attribute msg. I tried accessing attrs.msg in template function and it return value.type.

  2. If not then, Is it good to manipulate template under linker or I need to move it to compile function?

Upvotes: 7

Views: 5150

Answers (2)

link
link

Reputation: 1676

To render a different template based on value.type you can use the ng-switch statement:

<div ng-switch="value.type">
    <div ng-switch-when="type1">
        //...template for type 1 here...
    </div>
    <div ng-switch-when="type2">
        //...template for type 2 here...
    </div>
</div>

Also, if I understood your second question: manipulation of the uncompiled directive should be done in the compile function, all the manipulation which occurs after compilation should go in the link function.

Docs for ngSwitch

EDIT: +1 to Sebastian for understanding what you wanted. However, what he is proposing is essentially reinventing the wheel, since it is essentially compiling and inserting the template manually (which is what ngSwitch does for you). Also, you can access the attributes you put on your directive through the attrs argument of the link function.

Upvotes: 7

Sebastian
Sebastian

Reputation: 17423

In the template function you don't have access to the scope of your directive. If you want to control what gets rendered you can do this using conditional logic (e.g. ng-switch) in a global template as suggested by simoned or use a link function:

.directive('cusMsgText', function($compile) {
  return {
    restrict: 'E',
    scope: {
      msg: '=',
      item: '='
    },
    link: function(scope, element, attrs) {
      templates = {
        x: '<div>template x {{item.name}}</div>',
        y: '<div>template y {{item.name}}</div>'
      };

      var html = templates[scope.msg];
      element.replaceWith($compile(html)(scope));
    }
  };
});

Upvotes: 4

Related Questions