AngularJS指令中的transclude

transclude可以设置为false(默认),true或者对象三种值,如果不设该属性就默认为false,也就是说你不需要将该指令所在元素包含的内容嵌入到模板中。

一、transclude设置为true

当transclude为true的时候,这时指令所在元素包含的内容会被嵌入到模板中有ng-transclude指令的元素中,例如:

<hello>
  	<p>hello</p>
<hello>
angular.module("app", []).directive('hello', ['', function() {
    return {
        restrict: 'E',
        template: '<div ng-transclude></div>',
        transclude: true,
        scope:{}
    }
}]);

运行结果

<hello>
	<div ng-transclude>
		<p>hello</p>
	</div>
<hello>

二、transclude设置为对象

当指令元素包含的内容需要嵌入到指令模板不同地方的时候,这个时候就要把transclude设置为对象

<panel>
    <panel-header>标题</panel-header>
    <panel-body>内容</panel-body>
    <panel-footer>页脚</panel-footer>
</panel>
angular.module("app", []).directive('panel', ['', function() {
    return {
        restrict: 'E',
        replace: true,
        transclude: {
            'header': '?panelHeader',
            'body'	: 'panelBody',
            'footer': '?panelFooter'
        },
        template: '
            <div class="panel">
                <div class="panel-header" ng-transclude="header"></div>
                <div class="panel-body" ng-transclude="body"></div>
                <div class="panel-footer" ng-transclude="footer"></div>
            </div>'
    }
}]);

运行结果

<div class="panel">
    <div class="panel-header" ng-transclude="header">
        <panel-header class="ng-binding ng-scope">标题</panel-header>
    </div>
    <div class="panel-body" ng-transclude="body">
        <panel-body class="ng-binding ng-scope">内容</panel-body>
    </div>
    <div class="panel-footer" ng-transclude="footer">
        <panel-footer class="ng-binding ng-scope">页脚</panel-footer>
    </div>
</div>

这里指令元素内部有三个指令,这三个指令(panel-header、panel-body、panel-footer)必须以E的形式调用,它们分别要插入到模板的不同位置,tranclude指定了要插入的位置,transclude是一个键值对的对象,key指定了要插入模板的位置,value就是要插入的内容,?代表这个嵌入点不一定有指令存在,否则必须在这个点插入指令,不然会报错。
值得注意的是,这个实例也证明了一点,指令包含的元素的作用域继承自指令的父作用域而不是隔离作用域。

三、$transclude

除了使用ng-transclude指令指定内容嵌入的地方外,还可以使用$transclude指令实现。

<hello>
	<span></span>
</hello>
angular.module("app", []).directive('hello', () =>{
    return {
        restrict: 'E',
        transclude: true,
        controller: ['$scope', '$element', '$transclude', function ($scope, $element, $transclude) {
            $transclude(function(clone) {
                //$element.find只能通过标签名进行查找
                $element.find('span').append(clone);
            });
        }],
        template: '<div><span></span></div>',
        scope: {}
    }
});

运行结果

<hello>
    <div>
        <span>
            <span class="ng-binding ng-scope"></span>
        </span>
    </div>
</hello>

其中控制器中的$element就是编译了之后的模板,而$transclude中的参数clone则是被编译了的指令包含的内容。两者可以同时对模板和内容进行处理。

四、compile

除了使用ng-transclude指令指定内容嵌入的地方外,还可以使用compile中指定第三个transcludeFn参数

<hello>
	<span></span>
</hello>
angular.module("app", []).directive('hello', ['', function() {
    return {
        restrict: 'E',
        transclude: true,
        compile: function(tElement, tAttrs, transcludeFn) {
            return function(scope, element, attrs) {
                scope.action = "hello";
                transcludeFn(scope, function(clone) {
                    element.find('span').append(clone);
                });
            };
        },
        template: '<div><span></span></div>',
        scope: {}
    }
}]);
<hello>
    <div>
        <span>
            <span class="ng-binding ng-scope"></span>
        </span>
    </div>
</hello>

这个文件实现了以上控制器中相同的功能,transcludeFn接受两个参数,一个scope作用域,一个函数,和controller一样,这个函数的参数clone就是编译之后的要嵌入的内容。唯一不同的是,编译这个clone的作用域是传进去的第一个参数,而controller中clone是继承了指令的父作用域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值