Angularjs 如何使angular.js重新评估/重新编译内部html?

Angularjs 如何使angular.js重新评估/重新编译内部html?,angularjs,angularjs-directive,interpolation,Angularjs,Angularjs Directive,Interpolation,我正在制作一个指令来修改它的内部html。迄今为止的代码: .directive('autotranslate', function($interpolate) { return function(scope, element, attr) { var html = element.html(); debugger; html = html.replace(/\[\[(\w+)\]\]/g, function(_, text) { re

我正在制作一个指令来修改它的内部html。迄今为止的代码:

.directive('autotranslate', function($interpolate) {
    return function(scope, element, attr) {
      var html = element.html();
      debugger;
      html = html.replace(/\[\[(\w+)\]\]/g, function(_, text) {
        return '<span translate="' + text + '"></span>';
      });
      element.html(html);
    }
  })
指令('autotranslate',函数($interpolate){ 返回函数(范围、元素、属性){ var html=element.html(); 调试器; html=html.replace(/\[\[(\w+)\]\]\]/g,函数(\,文本){ 返回“”; }); html(html); } }) 它可以工作,只是内部html不是由angular计算的。我想重新评估
元素的子树。有办法吗


谢谢:)

您必须
$compile

.directive('autotranslate', function($interpolate, $compile) {
    return function(scope, element, attr) {
      var html = element.html();
      debugger;
      html = html.replace(/\[\[(\w+)\]\]/g, function(_, text) {
        return '<span translate="' + text + '"></span>';
      });
      element.html(html);
      $compile(element.contents())(scope); //<---- recompilation 
    }
  })
指令('autotranslate',函数($interpolate,$compile){ 返回函数(范围、元素、属性){ var html=element.html(); 调试器; html=html.replace(/\[\[(\w+)\]\]\]/g,函数(\,文本){ 返回“”; }); html(html);
$compile(element.contents())(scope);//这比@Reza的解决方案效果更好

.directive('autotranslate', function() {
  return {
    compile: function(element, attrs) {
      var html = element.html();
      html = html.replace(/\[\[(\w+)\]\]/g, function(_, text) {
        return '<span translate="' + text + '"></span>';
      });
      element.html(html);
    }
  };
})
.directive('autotranslate',function(){
返回{
编译:函数(元素、属性){
var html=element.html();
html=html.replace(/\[\[(\w+)\]\]\]/g,函数(\,文本){
返回“”;
});
html(html);
}
};
})

scope
是它所有子元素的作用域时,Reza的代码工作。但是,如果此指令的某个子节点中有ng控制器或其他内容,则找不到作用域变量。但是,使用此解决方案^,它只起作用!

这里有一个更通用的方法来解决此问题:

angular.module('kcd.directives').directive('kcdRecompile', function($compile, $parse) {
  'use strict';
  return {
    scope: true, // required to be able to clear watchers safely
    compile: function(el) {
      var template = getElementAsHtml(el);
      return function link(scope, $el, attrs) {
        var stopWatching = scope.$parent.$watch(attrs.kcdRecompile, function(_new, _old) {
          var useBoolean = attrs.hasOwnProperty('useBoolean');
          if ((useBoolean && (!_new || _new === 'false')) || (!useBoolean && (!_new || _new === _old))) {
            return;
          }
          // reset kcdRecompile to false if we're using a boolean
          if (useBoolean) {
            $parse(attrs.kcdRecompile).assign(scope.$parent, false);
          }

          // recompile
          var newEl = $compile(template)(scope.$parent);
          $el.replaceWith(newEl);

          // Destroy old scope, reassign new scope.
          stopWatching();
          scope.$destroy();
        });
      };
    }
  };

  function getElementAsHtml(el) {
    return angular.element('<a></a>').append(el.clone()).html();
  }
});
编辑
如果您正在看这个,我会认真地建议您查看版本,因为它可能更为最新。

我使用它的目的是:重新编译已编译的元素是不正确的(请参阅下面@kornbridge的解决方案中报告的问题).@jerico在
link
函数中,除非您使用
compile
函数,否则在操作
DOM
时必须重新编译。您提到了@kornbridge的解决方案,他使用了
compile
函数。根据文档,我认为这不是使用
compile的合适用例e> 函数。@Reza:IMO编译函数可以工作,但也不是最好的解决方案。OP的意图可能最好通过在服务器上或编译前操作标记来实现。这是一个高性能和稳定的解决方案,因为它完全消除了在翻译中对角度绑定的需要。请参阅Google的t(在视频中大约从42:34开始)。@Reza:您引用的文档说明编译函数是为了操纵标记的结构,而链接函数只是为了将其绑定到一个范围。由于OP想要操纵标记,包括绑定,我想说这显然是编译函数的一个用例(但在这种特殊情况下,请参阅我的其他评论,以获得更好的解决方案)。@Adam Barthelson,哈哈,谢谢:-)事实上,我最近在我的网站上更新了这个。所以我建议查看一下网站的版本。这个指令可以用来触发angular 1.2中的重新遵从吗?我必须使用angular 1.3中的一次性绑定表达式吗?有人能解释我:
返回angular.element(“”).append(el.clone()).html();
是,
html()
返回元素的内容。因为我们还需要
el
的根节点,所以我们首先将其插入一个伪元素中,然后获取该元素的内容。从指令中访问$parent作用域会破坏封装。如果要这样做,则需要一个parent指令(请参见Angular Direction配置对象的require属性)以支持的方式建立这种依赖关系。@kornifridge您能否清楚地说明当作用域是它所有子元素的作用域时,
Reza的代码起作用?它是如何更好地工作的?根据文档,使用
compile
函数的最佳实践是
可以在directi实例之间共享的任何操作出于性能原因,应将ves移到编译函数。
<div kcd-recompile="recompile.things" use-boolean>
  <div ng-repeat="thing in ::things">
    <img ng-src="{{::thing.getImage()}}">
    <span>{{::thing.name}}</span>
  </div>
</div>
$scope.recompile = { things: false };
$scope.$on('things.changed', function() { // or some other notification mechanism that you need to recompile...
  $scope.recompile.things = true;
});