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

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

index.html

<!DOCTYPE html>
<html ng-app="myapp">
<head>
<meta charset="utf-8">
<title>angular test</title>
</head>
<body ng-controller="myCtrl">
<div hello="{{name}}">你好</div>
</body>
<script src="./node_modules/angular/angular.js"></script>
<script src="./index.js"></script>
</html>

index.js

let app = angular.module('myapp',[]);
app.controller('myCtrl', $scope =>{
$scope.name = "Jhon";
});
app.directive('hello', () =>{
return {
restrict: 'A',
template: '<div><span ng-transclude></span>{{name}}</div>',
transclude: true,
scope:{
name: "@hello"
}
}
});

运行之后的效果如下:

<div hello="Jhon" class="ng-isolate-scope">
<div class="ng-binding">
<span ng-transclude="">你好</span>
Jhon
</div>
</div>

当指令元素包含的内容需要嵌入到指令模板不同地方的时候,这个时候就要把transclude设置为对象,例如下面这个我在项目中使用的一个例子:

index.html

<!DOCTYPE html>
<html ng-app="myapp">
<head>
<meta charset="utf-8">
<title>angular test</title>
</head>
<body ng-controller="myCtrl">
<panel>
<panel-header>{{title}}</panel-header>
<panel-body>{{content}}</panel-body>
<panel-footer>{{footer}}</panel-footer>
</panel>
</body>
<script src="./node_modules/angular/angular.js"></script>
<script src="./index.js"></script>
</html>

index.js

let app = angular.module('myapp',[]);
app.controller('myCtrl', ['$scope', $scope =>{
$scope.title = "标题";
$scope.content = "内容";
$scope.footer = "页脚";
}]);
app.directive('panel', () =>{
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>

这里指令元素内部有三个指令,这三个指令必须以E的形式调用,它们分别要插入到模板的不同位置,tranclude指定了要插入的位置,transclude是一个键值对的对象,key指定了要插入模板的位置,value就是要插入的内容,?代表这个嵌入点不一定有指令存在,否则必须在这个点插入指令,不然会报错。

值得注意的是,这个实例也证明了一点,指令包含的元素的作用域继承自指令的父作用域而不是隔离作用域。

除了使用ng-transclude指令指定内容嵌入的地方外,我们还有两种方法可以做到这点。

第一种就是在控制器中使用$transclude服务,例如以下代码:

index.html

<!DOCTYPE html>
<html ng-app="myapp">
<head>
<meta charset="utf-8">
<title>angular test</title>
</head>
<body ng-controller="myCtrl">
<hello name="{{name}}"><span>{{action}}</span></hello>
</body>
<script src="./node_modules/angular/angular.js"></script>
<script src="./index.js"></script>
</html>

index.js

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

最后显示的结果如下:

<hello name="Jhon" class="ng-isolate-scope">
<div class="ng-binding">
<span>
<span class="ng-binding ng-scope">
你好
</span>
</span>
Jhon
</div>
</hello>

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

另一种方法是在compile中指定第三个transcludeFn参数,如下所示:

index.js

let app = angular.module('myapp',[]);
app.controller('myCtrl', ['$scope', $scope =>{
$scope.name = "Jhon";
$scope.action = "你好";
}]);
app.directive('hello', () =>{
return {
restrict: 'E',
transclude: true,
compile: (tElement, tAttrs, transcludeFn) =>{
return (scope, element, attrs) =>{
scope.action = "hello";
transcludeFn(scope, (clone) =>{
element.find('span').append(clone);
});
};
},
template: '<div><span></span>{{name}}</div>',
scope: {
name: '@'
}
}
});

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

angular高级篇之transclude使用详解的更多相关文章

  1. SaltStack 入门到精通第三篇:Salt-Minion配置文件详解

    SaltStack 入门到精通第三篇:Salt-Minion配置文件详解 作者:ArlenJ  发布日期:2014-06-09 17:52:16   ##### 主要配置设置 ##### 配置 默认值 ...

  2. Farseer.net轻量级开源框架 入门篇:查询数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 下一篇:Farseer.net轻量级开源框架 中级篇: Where条 ...

  3. Mysql高手系列 - 第19篇:mysql游标详解,此技能可用于救火

    Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第19篇. 环境:mysql5.7.25,cmd命令中进行演示. 代码中被[]包含的表示可选,|符 ...

  4. SaltStack 入门到精通第二篇:Salt-master配置文件详解

    SaltStack 入门到精通第二篇:Salt-master配置文件详解     转自(coocla):http://blog.coocla.org/301.html 原本想要重新翻译salt-mas ...

  5. Farseer.net轻量级开源框架 入门篇:添加数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 分类逻辑层 下一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 ...

  6. Farseer.net轻量级开源框架 入门篇:修改数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 ...

  7. Farseer.net轻量级开源框架 入门篇:删除数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 查询数据详解 ...

  8. Mysql高手系列 - 第12篇:子查询详解

    这是Mysql系列第12篇. 环境:mysql5.7.25,cmd命令中进行演示. 本章节非常重要. 子查询 出现在select语句中的select语句,称为子查询或内查询. 外部的select查询语 ...

  9. 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)

    1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...

随机推荐

  1. python基础之五大标准数据类型

    学习一门语言,往往都是从Hello World开始. 但是笔者认为,在一个黑框框中输出一个"你好,世界"并没有什么了不起,要看透事物的本质,熟悉一门语言,就要了解其底层,就是我们常 ...

  2. Codeforces Round #436 (Div. 2) C. Bus

    http://codeforces.com/contest/864/problem/C 题意: 坐标轴上有x = 0和 x = a两点,汽车从0到a之后掉头返回,从a到0之后又掉头驶向a...从0到a ...

  3. oracle pctfree和pctused 详解

    一.建立表时候,注意PCTFREE参数的作用 PCTFREE:为一个块保留的空间百分比,表示数据块在什么情况下可以被insert,默认是10,表示当数据块的可用空间低于10%后,就不可以被insert ...

  4. oracle 数据库管理员

    一.数据库管理员每个oracle数据库应该至少有一个数据库管理员(dba),对于一个小的数据库,一个dba就够了,但是对于一个大的数据库可能需要多个dba分担不同的管理职责.那么一个数据库管理员的主要 ...

  5. AngularJS -- Bootstrap(启动器)

    点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ Bootstrap(初始化) 这章介绍了Angular的初始化过程,以及如何在必要的时候 ...

  6. Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

    Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...

  7. pytorch实现VAE

    一.VAE的具体结构 二.VAE的pytorch实现 1加载并规范化MNIST import相关类: from __future__ import print_function import argp ...

  8. Floyd算法(最短路)

    如题,这是最短路算法Floyd. Floyd,是只有五行的代码. 简单,易懂.O(N的三方)的时间也可以. 遇到简单的就这么用. #include<iostream> #include&l ...

  9. ObjectSNMP

    下面的例子,就是使用ObjectSNMP获取RFC1213-MIB的例子:其中的system和ifTable对象就是对应的SNMPMIB中的system组合interface中的ifTable表. p ...

  10. 机器学习-KNN分类器

    1.  K-近邻(k-Nearest Neighbors,KNN)的原理 通过测量不同特征值之间的距离来衡量相似度的方法进行分类. 2.  KNN算法过程 训练样本集:样本集中每个特征值都已经做好类别 ...