AngularJS:在手动转换后是否可以编译ng-repeat注​​释?

时间:2014-08-26 01:00:23

标签: javascript angularjs angularjs-directive angularjs-ng-repeat

Plunkr:http://plnkr.co/edit/zYd13f4EelPcQqJrguVh?p=preview

var app = angular.module("inputGroupApp", []);

app.controller('numbersController', ['$scope', function($scope){

  $scope.data = {}
  $scope.data.numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}]);


app.directive('labelGroup', ['$compile', '$timeout', function($compile, $timeout) {
    return {
      'template'   : '<div class="label-group">' +
                     '<label class="label-group-label"></label>' +
                     '<div class="label-group-content"></div>' +
                     '</div>',
      'restrict'   : 'E',
      'transclude' : true,
      'replace'    : true,
      'link'       : function(scope, elem, attr, nullController, transclude) {

        var labelElem = elem.find('.label-group-label');
        var contentElem = elem.find('.label-group-content');

        transclude(scope, function(clone) {
          var tLabel = null;
          var tContent = null;

          angular.forEach(clone, function(node) {
            var $node = angular.element(node);

            // these nodes have been emptied by gutting their contents
            // is it a memory problem that the nodes themselves aren't destroyed?

            if ($node.is('label-group-label')) {
              tLabel = $node.contents(); 
              labelElem.append(tLabel);
            } else if ($node.is('label-group-content')) {
              tContent = $node.contents();
              contentElem.append(tContent);
            }
          });

          // why doesn't this work? i've tried compiling elem with no success either
          $compile(contentElem)(scope);

          console.log('contentElem ', contentElem);
          console.log('elem ', elem);
        });
      }
    };
  }]);

我尝试编写标记抽象指令,使用自定义元素包装标签和相应内容,这些元素在将内容放置在新模板中时将被丢弃。标签组的内容部分可以包含指令,并且需要成功编译。

我似乎无法工作的唯一部分是让尚未渲染的转换dom元素(在本例中为ng-repeat)实际编译。我成功地复制了ng-repeat注​​释,但是当我尝试运行时使用$ compile来使ng-repeat编译没有任何反应。任何反馈将不胜感激。

我开始认为我可能会错误地解决这个问题。

1 个答案:

答案 0 :(得分:0)

事实证明我在运行编译之前尝试修改了被转换克隆的dom结构,特别是从父包装器中删除了嵌套的ng-repeat注​​释。由于angular通过父元素维护范围引用,这有效地导致ng-repeat按预期运行,因为它没有要重复的范围数据(所以它只是作为注释保留)。

我想出的解决方案是在transclude函数中运行编译步骤,然后通过在transclude函数之外附加节点来修改dom。

这里是更新的代码,它将被转换的元素追加到transclude函数之外以及它们被编译后。

http://plnkr.co/edit/E3Ha0xS6NUFIefohKve9?p=preview

var app = angular.module("inputGroupApp", []);

app.controller('numbersController', ['$scope', function($scope){

  $scope.data = {}
  $scope.data.numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}]);


app.directive('labelGroup', ['$compile', '$timeout', function($compile, $timeout) {
    return {
      'template'   : '<div class="label-group">' +
                     '<label class="label-group-label"></label>' +
                     '<div class="label-group-content"></div>' +
                     '</div>',
      'restrict'   : 'E',
      'transclude' : true,
      'replace'    : true,
      'link'       : function(scope, elem, attr, nullController, transclude) {

        var labelElem = elem.find('.label-group-label');
        var contentElem = elem.find('.label-group-content');

        var tLabel = null;
        var tContent = null;

        transclude(scope, function(clone) {


          angular.forEach(clone, function(node) {
            var $node = angular.element(node);

            // these nodes have been emptied by gutting their contents
            // is it a memory problem that the nodes themselves aren't destroyed?

            if ($node.is('label-group-label')) {
              tLabel = $node.contents(); 
            } else if ($node.is('label-group-content')) {
              tContent = $node.contents();
            }
          });

          $compile(contentElem)(scope);
          $compile(labelElem)(scope);

        });

      contentElem.append(tContent);
      labelElem.append(tLabel);
      }
    };
  }]);