Angularjs:理解递归指令 [英] Angularjs: understanding a recursive directive

查看:32
本文介绍了Angularjs:理解递归指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里找到了一个很棒的树指令.原文:http://jsfiddle.net/n8dPm/

I found a great tree directive here. Original: http://jsfiddle.net/n8dPm/

我一直试图通过其他几个 SO 问题来了解它的功能,1,2.我不太明白渲染树指令的递归调用是如何工作的.主要是编译功能

I have been trying to understand the functioning of it through couple of other SO questions, 1,2 . I couldn't quite understand how the recursive calls to render the tree directive work. Mainly the compile function

  1. 什么时候调用所有编译函数?
  2. $compile 函数何时缓存在变量 compiledContents 中(这是链接函数吗?),何时附加?为什么不总是追加?
  1. When all the compile function called?
  2. When is the $compile function cached in the varibale compiledContents (is this the link function?), and when is it appends? Why it is not append always?

--

compile: function(tElement, tAttr) {
            var contents = tElement.contents().remove();
            var compiledContents;
            return function(scope, iElement, iAttr) {
                if(!compiledContents) {
                    compiledContents = $compile(contents);
                }
                compiledContents(scope, function(clone, scope) {
                         iElement.append(clone); 
                });
            };
        },

推荐答案

Ng 站点有一些很棒的文档(我认为其中一些是最好的).启动和运行时循环的概述非常有用:http://docs.angularjs.org/guide/concepts

The Ng site has some great documentation (some of the best around in my opinion). The overview of the Startup and Runtime loops are very helpful: http://docs.angularjs.org/guide/concepts

在高层次上,当 Ng 首次启动时,它会从 ng-app 所在的位置开始编译 DOM(就像 Ng 的另一个指令一样对待).这意味着它遍历元素并查找需要链接到 $rootScope(所有范围的根,这些范围是由编译/链接过程设置的原型继承链的一部分)的指令和表达式.如果它是一个指令,编译过程也在它上面完成.编译过程采用它在 HTML 中找到的所有 Ng 指令,并根据分配的优先级对它们进行优先级排序或假设优先级为零.当它把它们全部排序后,它会为返回链接函数的指令执行编译函数.在上面的例子中有两个显示链接函数,我将在下面注释它们以及将它链接到这个解释的其他注释.链接函数还以嵌入对象的形式提供了元素中的 HTML,该元素中的指令是属性、类或元素.

At a high level, when Ng first starts it compiles the DOM starting at where ng-app is located (treated like just another directive by Ng). This means it goes through the elements and looks directives and expressions it needs to link up to the $rootScope (the root of all scopes that are part of the prototypical inheritance chain setup by the compiling/linking process). If it is a directive, the compile process is done on it as well. The compiling process takes all of the Ng directives it finds in the HTML and prioritizes them based on there assigned priority or assumes the priority is zero. When it has them all ordered it executes the compile function for the directive which returns the link function. In the above example there are two show link functions which I will annotate below along with other notes linking it to this explanation. the link function also is given the HTML that was in the element the directive was a attribute, class, or element on in the form of the transclude object.

链接函数被执行,链接作用域和指令并产生一个视图.这可能包括 HTML/transclude,因此可以将其添加到指令 ng-transclude 在指令模板中的位置(这将应用与它的模板相同的过程作为 transclude).

The link functions are executed which links the scope and the directive along with producing a view. This may include the HTML/transclude so it can be added where the directive ng-transclude is in the template of the directive (which will have the same process applied to it with it's template being the transclude).

这里是我对上面稍微更正的自定义指令的注释:

So here are my notes for the slightly corrected custom directive above:

module.directive("tree", function($compile) {
    //Here is the Directive Definition Object being returned 
    //which is one of the two options for creating a custom directive
    //http://docs.angularjs.org/guide/directive
    return {
        restrict: "E",
        //We are stating here the HTML in the element the directive is applied to is going to be given to
        //the template with a ng-transclude directive to be compiled when processing the directive
        transclude: true,
        scope: {family: '='},
        template:       
            '<ul>' + 
                //Here we have one of the ng-transclude directives that will be give the HTML in the 
                //element the directive is applied to
                '<li ng-transclude></li>' +
                '<li ng-repeat="child in family.children">' +
                    //Here is another ng-transclude directive which will be given the same transclude HTML as
                    //above instance
                    //Notice that there is also another directive, 'tree', which is same type of directive this 
                    //template belongs to.  So the directive in the template will handle the ng-transclude 
                    //applied to the div as the transclude for the recursive compile call to the tree 
                    //directive.  The recursion will end when the ng-repeat above has no children to 
                    //walkthrough.  In other words, when we hit a leaf.
                    '<tree family="child"><div ng-transclude></div></tree>' +
                '</li>' +
            '</ul>',
        compile: function(tElement, tAttr, transclude) {
            //We are removing the contents/innerHTML from the element we are going to be applying the 
            //directive to and saving it to adding it below to the $compile call as the template
            var contents = tElement.contents().remove();
            var compiledContents;
            return function(scope, iElement, iAttr) {

                if(!compiledContents) {
                    //Get the link function with the contents frome top level template with 
                    //the transclude
                    compiledContents = $compile(contents, transclude);
                }
                //Call the link function to link the given scope and
                //a Clone Attach Function, http://docs.angularjs.org/api/ng.$compile :
                // "Calling the linking function returns the element of the template. 
                //    It is either the original element passed in, 
                //    or the clone of the element if the cloneAttachFn is provided."
                compiledContents(scope, function(clone, scope) {
                        //Appending the cloned template to the instance element, "iElement", 
                        //on which the directive is to used.
                         iElement.append(clone); 
                });
            };
        }
    };
});

整个工作:http://jsfiddle.net/DsvX6/7/

这篇关于Angularjs:理解递归指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆