AngularJS: $ manual compilation and natural recursive directive compilation

I tried to create my own recursive directive using AngularJS, which calls itself to convert an object into a representation using a pretty JSON format. Well, at first I used ng-include, calling the script with the template, with ng-if inside it, checking if the current value was the object, if any, the template call itself.

I always think this is a clumsy way to do this, so I am transforming into a directive, much easier.

More and less ... Because I discovered the world of recursive directives and found a lot of things, and the most interesting. I even read it in the Angular source code on github (I recommend you read: https://github.com/angular/angular.js ), and that was good.

I searched so hard and I thinkg I'm almost looking for an awser who will cherish my heart! Because I learn a lot, and you guys will help me.

See my code at the link below: https://github.com/Daymannovaes/htmljs/blob/master/js/directives/recursiveDataTemplateDirective.js

My directive: recursive-data-template = "data", where the data is an object. This directive will iterate over the key and values โ€‹โ€‹of this object, and if the value was an object, do it again. The condition is satisfied using ng-if = "isObject (value)".

Well, my first problem was an endless loop. I need to delete the content at compile time and then force compile the content in the postLink phase. My question is: ** Why doesn't manual compilation fall into the same infinite loop problem? **

I am compiling the same content, no conditions (if if (! CompiledContent) has been deleted, the infinite loop still does not occur), the difference is (I think), they only fade out elsewhere, but I could not find anyone on the Internet who interests me!

So thanks! (if the link doesn't work, here is the important code):

compile: function(templateElement, templateAttributes) { /* in compile time, we need to remove the innerHTML of template(url) because of its recursive. Because of its recusiveness, when the $compile start to read the DOM tree and find a recursiveDataTemplate directive (even its not will be evaluated all time by link function because the ng-if, whatever) its start the do all the process again. So, we need the .remove() */ var templateDirectiveContent = templateElement.contents().remove(); var compiledContent; return function($scope, linkElement, linkAttributes) { /* This verification avoid to compile the content to all siblings, because when you compile the siblings, don't work (I don't know why, yet). So, doing this we get only the top level link function (from each iteration) */ if(!compiledContent) { compiledContent = $compile(templateDirectiveContent); } /* Calling the link function passing the actual scope we get a clone object wich contains the finish viewed object, the view itself, the DOM!! Then, we attach the new dom in the element wich contains the directive */ compiledContent($scope, function(clone) { linkElement.append(clone); }); }; }, } 
 <ul> <li data-ng-repeat="(key, value) in fields"> <span data-ng-if="!isNumber(key)"> {{key}}: </span> <span data-ng-if="isObject(value)" recursive-data-template="value"></span> <span data-ng-if="!isObject(value)"> {{value}} </span> </li> </ul> 
+6
source share
2 answers

I believe this excerpt from the official documentation is relevant to what you ask:

Note. A compilation function cannot process directives that recursively use themselves in their own templates or compile functions. Compiling these directives leads to endless loops and errors. This can be avoided by using $compile with $compile in the postLink function to force the directive template to be compiled instead of relying on automatic layout of the templates using the template or templateUrl declaration or manual compilation inside the compilation function.

And based on the code you provided, you seem to have done what this note offers, that is, it is manually compiled inside the function (postLink) that you return for the compile property of your directive.

+1
source

About why compilation at the postLink stage rather than compile avoids endless recursion, since all DOM elements are compiled, they are actually used or not, whereas link will only start when the element is actually connected: for insteance, if higher ng-if is false, its child will not be pre-installed, and therefore neithr postLinked ... At least from my understanding!

I recommend this good article: http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives/

0
source

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


All Articles