zoukankan      html  css  js  c++  java
  • angularJS transclude

    参考来源:彻底弄懂AngularJS中的transclusion

    对以上文章进行摘录、总结和测试记录

    在使用指令的时候,如果想要使用指令中的子元素,那么你就要用transclusion。

    指令的DDO中,transclude有三个值: transclude: false |true | 'element' ;第一个是默认值,后两个有什么区别呢?

    transclude:'element'

    //TODO

    transclude:true

    <body ng-app="app">
    <dx>
        这是子元素
    </dx>
    </body>
    <script>
        var app = angular.module('app',[]);
        app.directive('dx',function() {
            return {
                transclude:true,
                template:'<div> 1233  <div ng-transclude></div> </div>'
            }
        });
    </script>

    运行结果:子元素会被嵌入进 <div ng-transclude></div> 里,而且拥有自己的作用域【后面会讲到这个作用域用来干嘛的】

    可以发现,模板中的ng-tranclude决定了在什么地方放置嵌入部分。

    以上仅仅只是嵌入了一次,如果我希望多次嵌入,怎么办?

     在代码中使用transclude。如下:

    link函数的第五个参数、compile函数的第三个参数、依赖注入的$transclude。三者用法一致(前两种用法中要求必须在DDO中打开transclude,如transclude:true,否则获取到的transclude为undefined)。以link为例:

    1.执行transclude函数,获取子元素

    <body ng-app="app">
    <dx>
        这是子元素
    </dx>
    </body>
    <script>
        var app = angular.module('app',[]);
        app.directive('dx',function() {
            return {
                transclude:'true',
                link:function(scope,ele,sttr,ctrl,transclude){
                    var sub = transclude();
                    for(var i = 0;i<3;i++){
                        ele.append(sub.clone());
                    }
                }
            }
        });

    运行结果如下,测试过程中发现在for循环运行之前,dx中的子元素被清空了,

    2.给transclude传递两个参数

    将以上案例修改如下:

     app.directive('dx',function() {
            return {
                transclude:'true',
                link:function(scope,ele,sttr,ctrl,transclude){
                    transclude(scope,function(sub){
                        for(var i = 0;i<3;i++){
                            ele.append(sub.clone());
                        }
                    });
                }
            }
        });

     运行效果没有发生任何变化。第二个参数中的sub,也还是当前指令的子元素。

    上面说过获取到的子元素都是有自己的作用域,第一个参数scope是这个子元素的上下文环境,子元素的作用域会继承这个上下文环境。

    例子:

    <body ng-app="app">
    这是外部的name:{{name}}
    <dx>
        这是我自定义的:{{name}}
    </dx>
    </body>
    <script>
        var app = angular.module('app',[]);
        app.directive('dx',function() {
            return {
                transclude:'true',
                link:function(scope,ele,sttr,ctrl,transclude){
                    scope.name = 7777;
                    var myScope = scope.$new();
                    myScope.name = 1233;
                    transclude(myScope,function(sub){
                        ele.append(sub);
                    });
                }
            }
        });
    </script>

    运行结果:这是外部的name:7777 这是我自定义的:1233

    以上通过new从当前的作用域中衍生出一个新的作用域(新的作用域继承自当前作用域)。然后对新的作用域进行数据修改,最后应用到子元素上。


    对获取到的子元素进行进一步理解:

    <dx>
        这是我自定义的:{{name}}
    </dx>
    </body>
    <script>
        var app = angular.module('app',[]);
        app.directive('dx',function() {
            return {
                transclude:'true',
                link:function(scope,ele,sttr,ctrl,transclude){
                    var myScope = scope.$new();
                    myScope.name = 1233;
                    transclude(myScope,function(sub){
                        for(var i = 0;i<3;i++){
                            ele.append(sub.clone());
                        }
                    });
                }
            }
        });
    </script>

    运行结果:这是我自定义的:{{name}} 这是我自定义的:{{name}} 这是我自定义的:{{name}}

    显然这不是我们想要的,而且为什么会出现这样的结果?

    因为我们在循环中添加的只是克隆体,或者直接理解为添加的仅仅是一坨html而已,这和angular没有任何关系,自然也就不存在数据绑定的说法,所以文本就直接显示出来了。

    解决办法就是让这一坨html与angular扯上关系,进行手动编译,注入$compile服务,然后修改循环如下:

                    transclude(scope,function(sub){
                        for(var i = 0;i<3;i++){
                            var clone = sub.clone();
                            $compile(clone)(myScope);
                            ele.append(clone);
                        }
                    });

    以上transclude的第一个scope实际上已经没用了,因为手动编译的时候,我们指定了这个被编译元素的上下文,编译过程就会只读取这个上下文了。

    总结:transclude的第一个scope仅仅针对sub本身是有用的,而对于sub的克隆体来说没有任何用处

  • 相关阅读:
    Python
    版本控制
    后台
    前端
    提升权限 关闭系统
    SC命令(windows服务开启/禁用)
    获取当前电脑全部网络连接名字
    x64 win64编译环境下ADO链接Access数据库的问题解决
    Netsh命令-网络禁用开启
    windows主机防护
  • 原文地址:https://www.cnblogs.com/hellohello/p/7603680.html
Copyright © 2011-2022 走看看