1

This has been bothering me for about an hour now due to my lack of AngularJS proficiency. I am working through trying to understand directives. This example regarding capitalizing text from a directive seems clear, but how to you capitalize text in the following example through a directive without referring to "myMessage.description" within the directive?

<td my-directive>{{myMessage.description}}</td>

I know its staring me right in the face, but I cannot seem to find a direct answer to this probably because I am not phrasing my question correctly in my mind. My thought is that I would have to refer to something hanging off of attrs.value or attrs.text within the link function. If so, how do I update the view with the new value?

Community
  • 1
  • 1
Rai
  • 394
  • 5
  • 23
  • Can't you replace the content via `element.html(capitalisedValue)` or something similar? – Brendan Green Aug 07 '15 at 01:33
  • How do you reference the value that `capitalisedValue` is based upon? From the example he does `capitalize(scope[attrs.ngModel]);`, but this is not `ngModel`. – Rai Aug 07 '15 at 01:54
  • 2
    Get the value via `element.html()`, capitalise it, then write it back. – Brendan Green Aug 07 '15 at 02:00
  • Makes sense. I was doing this, but incorrectly trying to do that in the `link` function. Just realized this from the comment from shaunhusain. – Rai Aug 07 '15 at 02:48

1 Answers1

2

The typical way to transform text in a view is to just use a filter in the interpolation, there's a built in uppercase filter so you can just add |uppercase to the interpolated expression.

http://plnkr.co/edit/FbqLdnu3AAW83uy2w31u?p=preview

<p>Hello {{foo.bar|uppercase}}!</p>

Here's a way you could do it with a directive:

http://plnkr.co/edit/xADMMdyuklMgJ9IdmocT?p=preview

 .directive('upperCase', function($interpolate){
    return {
      // Compile function runs before children are compiled/processed
      // so we get the initial contents in this function
      compile:function(iElem, iAttrs){

        var curContents = iElem.html();
        //After we grab the contents we empty out the HTML so
        //it won't be processed again.
        iElem.html('');

        // The compile function can return a link function
        // this gets run to get the scope for the instance
        // and uses the $interpolate service to do the same
        // thing angular would do when it sees the {{}}
        // with the added step of running toUpperCase
        return function(scope, iElem, iAttrs){
          iElem.html($interpolate(curContents)(scope).toUpperCase())
        }
      }
    };
  });
shaunhusain
  • 19,630
  • 4
  • 38
  • 51
  • Thank you. This is what I was missing. I started down the path of using `$interpolate` after a short time, realized that `compile` function needed to be used. – Rai Aug 07 '15 at 02:50
  • 1
    Rai regarding the parameter names it doesn't really matter for compile or link functions only the order matters. When angular runs code through the $compile service it finds any directives and runs their compile function (parent elements first then children) it uses the result of that or if you just defined a link function and no compile and calls those link functions passing in the DOM element and scope so you can do work for the particular instance. I should have used the tElem and tAttr for the sake of convention. – shaunhusain Aug 09 '15 at 04:26