Angular Directive $ compile不编译内部指令

时间:2014-08-15 22:47:42

标签: angularjs

我正在尝试制作一组​​指令,这样我就可以重复大量数据而不会创建很多范围,因为范围需要花费很多秒才能清理Chrome的垃圾收集。

我的解决方案中的问题是我在for循环中调用了$compile,但是$ compile'd html中的指令没有针对循环的每次迭代进行求值。它只是在最后进行评估。

console.log输出:

lscope.name:  jason app.js:20
lscope.name:  fred app.js:20
lscope.name:  anthony app.js:20
lscope.name:  balory app.js:20
[div, jquery: "2.1.1", constructor: function, selector: "", toArray: function, get: function…] app.js:25

lessif:  true 

代码:

app.controller('MainCtrl', function($scope) {
    $scope.names = ['jason', 'fred', 'anthony', 'balory'];
});

app.directive('scopelessRepeat', function($compile) {
  console.log('scopeless repeat called');
    return {
      transclude: 'element',
      restrict: "AE",
      scope: false,
      link: function (lscope, lelement, lattrs, lcontroller, ltransclude) {
        console.log('attrs: ', lattrs);
        var root = $('<div></div>');
        ltransclude(lscope, function(transHtml) {
          for(var i=0; i!=lscope[lattrs.items].length; ++i){
           lscope[lattrs.key] = lscope[lattrs.items][i];
           console.log('lscope.name: ', lscope.name);
           $compile(transHtml.contents())(lscope, function cloneFn(cloneHtml) {
            root.append(cloneHtml);
           });
          }
          console.log(root);
          lelement.after(root);
        });
      },
    };
  });
    app.directive('lessIf', function($compile) {
      return {
        transclude: 'element',
        restrict: "AE",
        scope: false,
        priority: 1000,
        //link: function (lscope, lelement, lattrs, lcontroller, ltransclude) {
        controller: function ($scope, $element, $attrs) {
          console.log('lessif: ', $scope.$eval($attrs['lessIf']));
          if($scope.$eval($attrs['lessIf']))
            $element.replaceWith($compile($element)($scope));
          else 
            $element.replaceWith(' ');      
        },        
      };      
    });

为什么我的内部指令不会在每次迭代循环中被评估? (ps是的,我知道bind-once,但它对垃圾收集问题没有帮助,开发人员也没有回复我有关于一次绑定的多个上下文,所以我必须自己动手)< / p>

Plnkr:

1 个答案:

答案 0 :(得分:1)

这样做,你需要把ltransclude(..)放在循环中。

for (var i = 0; i != lscope[lattrs.items].length; ++i) {
    ltransclude(lscope, function(transHtml) {

      lscope[lattrs.key] = lscope[lattrs.items][i];
      $compile(transHtml.contents())(lscope, function cloneFn(cloneHtml) {
        root.append(cloneHtml);
      });

      lelement.after(root);
    });
  }