$ compile'ing已编译的元素不受支持,该怎么办?

时间:2014-09-19 22:54:25

标签: angularjs angularjs-directive angularjs-scope

根据lgalfaso on Angular.js repo

  

lgalfaso 8小时前评论过

     

重新编译已编译的元素是滥用而不是某种东西   支持的。我不知道你想做什么,但看起来像一个   stackoverflow的主题

提供的plunkr http://plnkr.co/edit/Y7FbPm?p=preview代码

angular
.module('app', [])
.controller('Main', function(){
    this.label = "Hello";
})
.directive('recompileMe', ['$compile', function($compile){
    return {
        restrict: 'A',
        compile: function(el, attrs){
            el.removeAttr('recompile-me');

            return function(scope, el){
                $compile(el)(scope, function(clone) {
                    el.replaceWith(clone);
                });
            };
        }
    }    
}])
.directive('transcludeMe', [function(){
    return {
        restrict: 'A',
        transclude: true,
        scope: {},
        template: '<div>Transcluded: <div ng-transclude></div></div>',
        link: function(scope, el, attr, controller, transclude){
        }
    }    
}]);

如果我需要为我的元素设置其他指令,我需要为要解析和应用的指令编译它,或者还有其他方法吗? (这个https://github.com/angular/angular.js/issues/9169)的另一个案例

2 个答案:

答案 0 :(得分:0)

为了编译一次,你可以在编译到达元素的子元素之前分离指令元素的子元素。然后,向子项添加指令,或者根据需要操作DOM。在链接阶段,重新附加子项,并使用$ compile服务来编译和链接子项。

.directive('recompileMe', ['$compile', function($compile){
    return {
        restrict: 'A',
        compile: function(el, attrs){
            // save the children
            var e2 = angular.element(el.html());

            // clear the children so they are not compiled
            el.empty();

            // add some directives
            e2.find('a').attr('my-directive', '');

            return function(scope, el){

                // reattach to DOM
                el.append(e2);

                // compile and link children
                $compile(e2)(scope);
           };
        }
    }    
}])

答案 1 :(得分:0)

这似乎是唯一正确的方法(即使在清除angular.js源代码之后),也是使用terminal: true。也就是说,您必须手动编译元素,然后执行DOM操作,如下所示:

angular.module('app', [])
.controller('main', ['$scope', function($scope){ 
  $scope.inner = 'Inner content';
}])
.directive('recompileMe', ['$compile', function($compile){
  return {
    restrict: 'A',
    terminal: true,
    priority: 10,
    compile: function(element){
      element.removeAttr('recompile-me');
      
      var compiled = $compile(element);

      return function(scope, el){
        compiled(scope);
      };
    }
  }
}])
.directive('transcludeMe', function(){
  return {
    restrict: 'A',
    transclude: true,
    template: '<div>Transcluded: <div ng-transclude></div></div>'
  };
});
<!doctype html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  </head>

  <body ng-app="app">
    <div ng-controller="main">
      <div recompile-me transclude-me><div ng-bind="inner"></div> Outside</div>
    </div>
  </body>
</html>