AngularJS:通过插值观察被转换的内容变化?

Phi*_*ice 4 javascript angularjs angularjs-directive

我把一个最能说明问题的傻瓜放在一起.

我正在尝试编写一个简单的指令,它将从指令更新transcluded html.

例如,我想:

<make-bold>Foo *bar* {{something}}</make-bold> 
Run Code Online (Sandbox Code Playgroud)

生成

<span>Foo <b>bar</b> somevalue<span>  
Run Code Online (Sandbox Code Playgroud)

关于plunker的例子工作得很好,但我无法弄清楚如何获得被转换内容的通知(观察)变化.在示例中,尝试选择不同的项目(通过单击它们),您将注意到"已处理"不会更新.

我很确定问题是传递给链接函数的元素没有更新,但它是内容更新,因此无法观看.

指示

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); });
      });

    }
  };
});
Run Code Online (Sandbox Code Playgroud)

模板

<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>
Run Code Online (Sandbox Code Playgroud)

(注意:我实际上并不想制作'make-bold'指令,但这说明了我遇到的问题.)

Ila*_*mer 18

这是一个工作的plunker

这个并不明显且非常具有挑战性.我必须查看angular.js源代码内部,以完全了解转换内容的实际位置以及内插文本的角度.

这里的技巧是禁用角度插值并手动使用$ interpolate.

compile.js中的 addTextInterpolateDirective函数 负责插值({{}})的魔术绑定.

稍后,我将通过详细解释更新此答案.

解:

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);
        });
      }
    }
  };
});
Run Code Online (Sandbox Code Playgroud)