2014-07-04 26 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服務注入到您的指令中。