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

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

问题描述

我发现了一个巨大的树指令在这里。原文: http://jsfiddle.net/n8dPm/

我一直在试图通过其他几个SO问题,以了解它的运作, 1 ,<一个href=\"http://stackoverflow.com/questions/19124986/angularjs-attaching-a-click-event-in-directive\">2 。我不太明白递归调用如何渲染树指令工作。主要是编译功能


  1. 在当前召集了所有的编译功能?

  2. 当是$编译功能在varibale compiledContents 缓存(这是链接功能?),当是其追加?为什么它并不总是追加?

-

 编译:功能(tElement,对tattr){
            VAR内容= tElement.contents()remove()方法。
            VAR compiledContents;
            返回功能(范围,iElement,iAttr){
                如果(!compiledContents){
                    compiledContents = $编译(内容);
                }
                compiledContents(范围,功能(克隆,范围){
                         iElement.append(克隆);
                });
            };
        },


解决方案

该网站显示有一些伟大的文档(一些各地最好的在我看来)。启动和运行循环的概述是非常有帮助的:
http://docs.angularjs.org/guide/concepts

在一个较高的水平,当吴先启动它编译DOM开始,其中n应用的位置(伍像对待只是一个指令)。这意味着它经历的元素,看起来指令和前pressions它需要长达链接到$ rootScope(/是原型继承链设置的一部分由编译链接过程中的所有范围的根目录)。如果它是一个指令,编译过程是在它作为做得很好。在编译过程需要所有的伍指示找到了HTML和他们优先的基础上有指定的优先级或承担的优先级是零。当它拥有所有这些下令执行编译函数返回的链接功能的指令。在上面的例子有两个显示链接的功能,我将它链接到这个解释其他注意事项下面一起注解。链接功能也是因为在该元素的指令是一个属性,类,或在transclude对象的形式元素的HTML。

链接功能执行它链接的范围,并产生一个视图沿指令。这可以包括在HTML / transclude所以它可以被添加,其中该指令纳克-transclude是在指令的模板(其将具有适用于它与它的模板作为transclude相同的处理)。

因此​​,这里有我上面稍微修正定制指令注意事项:

  module.directive(树,函数($编译){
    //这里被返回指令定义对象
    //这两个选项中的一个用于创建自定义指令
    //http://docs.angularjs.org/guide/directive
    返回{
        限制:E,
        //我们在这里说明在指令中被施加到将要提供给元素的HTML
        //用NG-transclude指令的模板来处理指令时,被编译
        transclude:真实,
        适用范围:{FAMILY:'='},
        模板:
            '&LT; UL&GT;' +
                //这里我们有NG-transclude指令之一,将给予在该HTML
                //该指令适用于元
                '&LT;李NG-transclude&GT;&LT; /李&GT;' +
                '&LT;李NG重复=孩子family.children&GT;' +
                    //这里是另一个纳克-transclude指令将被给予相同transclude HTML作为
                    //实例之上
                    //注意,也有另一种指令,'树',这是同类型的指令这一点
                    //模板属于。所以在模板中的指令将处理NG-transclude
                    //应用于div作为transclude的递归调用编译到树
                    //指示。递归将结束时,上面的NG-重复没有孩子
                    //演练。换句话说,当我们打叶。
                    '&LT;树家庭=孩子&GT;&LT; D​​IV NG-transclude&GT;&LT; / DIV&GT;&LT; /树&GT;' +
                '&LT; /李&GT;' +
            '&所述; / UL&GT;',
        编译:功能(tElement,对tattr,transclude){
            //我们删除的内容/ innerHTML的从元素,我们将要应用
            //指令,并将其保存到将其添加到下面的$编译调用作为模板
            VAR内容= tElement.contents()remove()方法。
            VAR compiledContents;
            返回功能(范围,iElement,iAttr){                如果(!compiledContents){
                    //获取链接功能与内容弗罗姆与顶级模板
                    //将transclude
                    compiledContents = $编译(内容,transclude);
                }
                //调用链接功能给定的范围和链接
                //克隆附加功能,http://docs.angularjs.org/api/ng.$compile:
                //调用链接函数返回模板的元件。
                //它要么是原始的元素来传递的,
                //或如果提供了cloneAttachFn元素的克隆。
                compiledContents(范围,功能(克隆,范围){
                        //追加克隆的模板实例元素,iElement
                        //在其上的指令是使用。
                         iElement.append(克隆);
                });
            };
        }
    };
});

整件事的工作:
http://jsfiddle.net/DsvX6/7/

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

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

解决方案

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

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.

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

Whole thing working: http://jsfiddle.net/DsvX6/7/

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

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