【问题标题】:AngularJS: Watch transcluded content change with interpolation?AngularJS:通过插值观察嵌入内容的变化?
【发布时间】:2014-01-09 01:53:28
【问题描述】:

我整理了一个plunker,最能说明我的问题。

我正在尝试编写一个简单的指令,该指令将从指令中更新嵌入的 html。

例如我想要:

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

生成成

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

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

    }
  };
});

模板

<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”指令,但这说明了我遇到的问题。)

【问题讨论】:

  • 所以你想得到你的 HTML 显示的文本然后重新插入它?
  • @blesh 我的结论是没有重新插值的好方法。如果默认插值行为不适合用例,那么正确的方法是禁用它并手动使用 $interpolate 和 $watch。在内部,默认行为本身是一个指令 (addTextInterpolateDirective)。
  • @blesh,正确。如果我观看 element.text(),我可以得到这种工作,但在执行“粗体格式”后它会再次触发,所以第二次它最终会剥离它。

标签: javascript angularjs angularjs-directive


【解决方案1】:

这是一个有效的plunker

这个不是很明显而且很有挑战性。 我必须查看 angular.js 源代码才能完全了解嵌入内容的位置以及 angular 对插值文本的作用。

这里的技巧是禁用角度插值并手动使用 $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);
        });
      }
    }
  };
});

【讨论】:

  • 我敢打赌,您使用的是原生降价指令或类似的东西。如果您需要更多帮助,我将很乐意参与。
  • 你认为我们可以为范围内的动态数据(本例)和基本的静态 html 文本提供一个通用指令吗?
  • 您可以查看interpolateFn,如果为null则为静态文本,无需设置手表。检查这个github.com/angular/angular.js/blob/v1.2.15/src/ng/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
  • 2013-10-18
相关资源
最近更新 更多