AngularJS: Watch for content changes with interpolation?

I put together a plunker that best illustrates my problem.

I am trying to write a simple directive that will update the transcluded html from the directive.

For example, I would like to have:

<make-bold>Foo *bar* {{something}}</make-bold> 

Generate in

<span>Foo <b>bar</b> somevalue<span>  

The plunker example works fine, but I can't figure out how to receive notifications (watch) of the changed content. In this example, try to select different elements (by clicking on them), and you will notice that "Processed" is not updated.

I am sure that the problem is that the element passed to the link function is not updated, but it updates the content, so it cannot be viewed.

Directive

app.directive('makeBold', function($interpolate, $timeout, $compile)
{

  var regex = new RegExp("\\*(.+?)\\*", 'g');
  var replace = "<b>$1</b>";

  return {
    restrict: 'E',
    transclude: true,
    replace: true,
    template: '<span ng-transclude></span>',
    link: function (scope, element, attrs)
    {
      scope.$watch(
        function() { 
          // *** What do I need to watch here? ***
          return element;
        }, 
        function(n, o) {
          var text = $interpolate(element.text())(scope); 
          var newContent = text.replace(regex, replace);
          $timeout(function() { element.html(newContent); });
      });

    }
  };
});

Template

<div ng-show="selected">
    <h1>{{selected.name}}</h1>
    <p><i>Original:</i> {{selected.detail}}</p>
    <p><i>Processed:</i> <make-bold>{{selected.detail}}</make-bold></p>
</div>

(. "make-bold", , .)

+4
1

plunker

. angular.js, , , angular .

, angular $.

addTextInterpolateDirective compile.js ({{}}).

.

:

app.directive('makeBold', function( $interpolate ) {

  var regex = new RegExp("\\*(.+?)\\*", 'g');
  var replace = "<b>$1</b>";

  return {
    restrict: 'E',
    scope: true,
    compile: function (tElem, tAttrs) {
      var interpolateFn = $interpolate(tElem.html(), true);
      tElem.empty(); // disable automatic intepolation bindings
      return function(scope, elem, attrs){
        scope.$watch(interpolateFn, function (value) {
          var newContent = value.replace(regex, replace);
          elem.html(newContent);
        });
      }
    }
  };
});
+18

All Articles