How to change the transferred content before compilation inside the directive?

What I want to do is to handle the transclude manually and modify the contents before pasting into the DOM:

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 }); } } 

In the source of angular.js, I found this example:

  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` 

but when I add clonedElement.appendTo(caption); inside the link function, it adds comment only with ng-repeat inside.

I need this because I need to hide all elements in this case

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

I need to change the template before compiling or the DOM after the ng-repeat extension. It would be better before because I can add logic using the ng-hide directive instead of the ng-hide class.

+6
source share
3 answers

jcubic. You do not need to use the $ compilation for what you are trying to do.

You can filter the "clone" of the translatable element and add css classes to the filtered nodes, but after that you must add the modified clone to the template (it is identified by the "element" attribute of the link function).

 element.append(clone) 

I created this jsfiddle for you.

If you still have other questions, please create a jsfiddle of your case. Better answer thanks

+3
source

I understand that a lot of time has passed since the publication of this question, but I hope you find the following useful.

I was quite long and hard in this matter (transclusion), I tried several ways to achieve what you need @jcubic, and finally I came across a solution that is really reliable and quite simple.

 ... 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 */ } } ... 

So, you can see that you have full control over your "translated" content, and you don’t even need to translate !:-)

ps. I tested it with Angular 1.4. Not sure if it works with the replacement: true (I did not want to test it, since this is a minor nuisance if it is not). You can use the preliminary and post links, as usual, you use in the compilation function, and you need to insert the compile command in your directive.

+3
source

If you use angular> 1.3 and ngTransclude in the template, you need to update not the clone, but redo the DOM, for example:

 elm.find('ng-transclude') 

http://jsfiddle.net/jhqkxgos/

but make sure compile found the elements if you update some of them that you need to access from the controller

0
source

Source: https://habr.com/ru/post/971769/


All Articles