2014-07-04 29 views
6

我想要做的,是通过手工来处理transclude和修改的内容之前,我插入到DOM:如何在编译指令之前修改transcluded内容?

return { 
    restrict: 'E', 
    transclude: true, 
    template: '<HTML>', 
    replace: true, 
    link: function(scope, element, attrs, ngModelCtrl, $transclude) { 

     var caption = element.find('.caption'); 

     $transclude(function(clone) { 
      console.log(clone); 
      clone.filter('li').addClass('ng-hide'); // this don't work 
      clone.addClass('ng-hide'); // same this one 
      clone.attr('ng-hide', 'true'); // same this one 
      $compile(clone)(scope.$new()).appendTo(caption); 
      caption.find('li').addClass('ng-hide'); // and this 
     }); 
    } 
} 

在angular.js源,我发现这个例子:

var templateElement = angular.element('<p>{{total}}</p>'), 
     scope = ....; 

    var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) { 
    //attach the clone to DOM document at the right place 
    }); 

    //now we have reference to the cloned DOM via `clonedElement` 

但当我在链接函数里面添加clonedElement.appendTo(caption);时,它只在ng-repeat里面添加注释。

我需要这个,因为我需要隐藏在这种情况下

<dropdown> 
    <li ng-repeat="item in items"><a>{{item.label}}</a></li> 
</dropdown> 

我需要之前修改模板编译或DOM NG-重复扩大后的所有元素。之前会更好,因为我将能够使用ng-hide指令而不是ng-hide类来添加逻辑。

回答

3

jcubic。你不需要使用$ compile来完成你想要做的事情。

您可以过滤transcluded元素'clone'并将css类添加到过滤的节点,但是之后必须将修改的复本附加到模板(它由链接函数的'element'属性标识) 。

element.append(clone) 

我为你创造了这个jsfiddle

如果您还有其他问题,请创建case.It的的jsfiddle将更好地做出回答THX

0

如果您使用的角模板> 1.3和ngTransclude,所以你需要更新不是克隆,但transcluded DOM,例如:

elm.find('ng-transclude') 

http://jsfiddle.net/jhqkxgos/

但一定要compile找到的元素,如果你更新了一些你需要从控制器

访问
3

我意识到自从发布这个问题已经很长时间了,但是我希望你会发现以下内容有用。

我在这个(包容性)业务中已经很长很长时间了,我尝试了几种方法来实现你@jcubic所需要的,最后我遇到了一个非常强大且相当简单的解决方案。

... 
replace: false, 
transclude: false, 
compile: function(tElement, tAttributes) { 

    // store your "transcluded" content of the directive in the variable 
    var htmlContent = tElement.html(); 
    // then remove it 
    tElement.html(''); 

    return function postLink(scope, elem, attrs) { 
     // then html var is available in your link! 
     var $html = $('<div />',{ html:htmlContent }); // for much easier manipulation (so you can use DOM functions - you can also manipulate directly on htmlContent string) 

     // so you can manipulate the content however you want 
     scope.myVariable = true; 
     $html.find('li').attr('ng-hide', 'myVariable'); // add native directive 
     $html.removeClass('inner-content').addClass('my-inner-content'); // add/remove class 
     $html.find('#myElement').attr('my-directive',''); // add custom directive etc. etc. 

     // after you finished you just need to compile your html and append your directive element - also however you want 
     // you also convert back $html to the string 
     elem.append($compile($html.html())(scope)); // append at the end of element 
     /* or: 
     elem.find('.my-insert-point').html($compile($html.html())(scope)); // append the directive in the specific point 
     elem.find('[my-transclude]').html($compile($html.html())($parent.scope)); // once the scope:true it will be the same as native transclusion ;-) 
     scope.variable = $html.html(); // or you can probably assign to variable and use in your template with bind-html-compile (https://github.com/incuna/angular-bind-html-compile) - may need $sce.trustAsHtml 
     */ 
    } 
} 
... 

所以你可以看到你有你的“transcluded”内容完全控制,你甚至不需要transclusion! :-)

ps。我用Angular 1.4测试了它。不知道它是否适用于替换:真(我没有麻烦测试它,因为如果它没有的话,它是一个小麻烦)。您可以使用通常在编译函数中使用的pre和post链接,并且需要将$ compile服务注入到您的指令中。