AngularJS:手动$ compile vs自然$ compile通过递归指令

day*_*aes 6 recursion compilation directive angularjs

我试图用AngularJS创建我自己的递归指令,它调用自己用一个漂亮的JSON格式转换视图中的对象.好吧,首先我使用了一个ng-include调用一个带有模板的脚本,在其中使用ng-if验证当前值是否是一个对象,如果是,模板调用本身.

我一直认为这是一种不可思议的方法,所以我在一个指令中转换,更加简单.

越来越少......因为我发现了递归指令的世界,发现了很多东西,而且最有趣.我甚至在github上给它读了Angular的源代码(我建议你阅读:https://github.com/angular/angular.js),这是一件好事.

我搜索得如此努力,我想我几乎找到了能够珍惜我心灵的美妙!因为我学到了很多新东西而且你们都会帮助我.

在下面的链接中查看我的代码:https://github.com/Daymannovaes/htmljs/blob/master/js/directives/recursiveDataTemplateDirective.js

我的指令是:recursive-data-template ="data",其中data是一个对象.该指令将遍历此对象的键和值,如果值是对象,则将再次执行此操作.使用ng-if ="isObject(value)"进行条件.

好吧,我的第一个问题是无限循环.我需要在编译阶段删除内容,然后在postLink阶段强制编译内容.我的问题:**为什么手动编译不会出现无限循环的同一问题?**

我正在编译相同的内容,没有条件(如果if(!compiledContent)被删除,无限循环仍然没有发生),差异(我认为)只是他们在不同的地方,但我不是'能够在互联网上找到一个能解决我问题的人!

所以谢谢!(如果链接不起作用,这里是重要的代码):

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); 
                });
            };
        },
  }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

miq*_*iqh 1

我相信官方文档中的这段摘录与您的要求相关:

注意: compile 函数无法处理在自己的模板或编译函数中递归使用自身的指令。编译这些指令会导致无限循环和堆栈溢出错误。可以通过$compilepostLink函数中手动使用命令式编译指令的模板来避免这种情况,而不是依赖于通过编译template函数templateUrl内部的声明或手动编译进行自动模板编译。

从您提供的代码来看,您似乎已经完成了本注释所建议的操作 - 也就是说,在您为compile指令的属性返回的函数(postLink)内手动编译。