Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 415
Uday Sawant Avatar asked May 02 '14 09:05

Uday Sawant


People also ask

Can a directive have a template in Angular?

Components are directives with templates. The only difference between Components and the other two types of directives is the Template. Attribute and Structural Directives don't have Templates. So, we can say that the Component is a cleaner version of the Directive with a template, which is easier to use.

Which directive can have a template?

The component directive is just a directive that attaches the template and style for the element, along with the specific behavior.

What is attribute directive What are the selectors for directives?

The attribute directive changes the appearance or behavior of a DOM element. These directives look like regular HTML attributes in templates. The ngModel directive which is used for two-way is an example of an attribute directive.


2 Answers

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.

like image 71
link Avatar answered Sep 24 '22 06:09

link


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));
    }
  };
});
like image 34
Sebastian Avatar answered Sep 25 '22 06:09

Sebastian