最近学习angular,今天将指令中的transclude
选项和ng-transclude
指令总结一下。本文演示用的angular版本为1.5.11
。
首先,angualar指令的transclude
选项有三种值:false
、true
、object
。transclude
字面意思就是嵌入,也就是说你需不需要将你的指令中的内容(注意不是指令的模板)嵌入到你的模板中去,默认是false
。如果你需要这种功能的话,那么就需要将transclude
设置为true
或者{...}
。如果将这个值设置为true
或者{...}
的话,那么就要配合angular
的ng-transclude
指令来进行使用。下面我们通过代码来学习如何使用。
<body ng-app="transcludeApp"> <div ng-controller="trascludeCtrl"> <my-dialog> my dialog contents,{{ name }} </my-dialog> </div> <script src="angular.js"></script> <script src="transclude.js"></script> </body>
我们在页面中使用了自定义指令my-dialog
,并且在该指令中添加了一段文本内容(指令中的内容)。
angular.module('transcludeApp',[]) .controller('trascludeCtrl',['$scope',function($scope) { $scope.name = 'Tobias'; }]) .directive('myDialog',function() { return { restrict: 'E',transclude: true,scope: {},templateUrl: 'my-dialog.html',link: function(scope) { scope.name = 'Jeff'; } }; });
<div class="alert"> directive template,{{ name }} <hr> <div ng-transclude>ng-transclude,{{ name }}</div> </div>
我们查看一下运行结果:
可以看到指令中的内容填充到了指令模板中ng-transclude
指令所在的元素中,ng-transclude
指令所在元素的内容会被指令内容替代,并且此时指令内容受指令外部的作用域控制;但是当指令中没有任何内容时(空格也不允许),ng-trasclude
指令所在元素的内容会显示出来,此时ng-trasclude
指令所在元素的内容受指令外部的作用域控制。下面看一下改动代码:
页面更改为
<body ng-app="transcludeApp"> <div ng-controller="trascludeCtrl"> <my-dialog></my-dialog> </div> <script src="angular.js"></script> <script src="transclude.js"></script> </body>
结果变为
接下来,我们来看一下有多个嵌入点的情况,这时指令中的transclude
选项是一个对象。请看代码:
<body ng-app="transcludeApp"> <div ng-controller="trascludeCtrl"> <my-dialog> my dialog content,{{ name }} <transclude-header>transclude header content,{{ name }}</transclude-header> <transclude-body>transclude body content,{{ name }}</transclude-body> <!-- <transclude-footer>transclude footer content,{{ name }}</transclude-footer> --> my dialog content footer,{{ name }} </my-dialog> </div> <script src="angular.js"></script> <script src="transclude.js"></script> </body>
angular.module('transcludeApp',transclude: { 'header': 'transcludeHeader','body': 'transcludeBody','footer': '?transcludeFooter',},link: function(scope) { scope.name = 'Jeff'; } }; });
<div class="alert"> directive template,{{ name }}</div> <hr> <div ng-transclude="header">ng-transclude-header,{{ name }}</div> <div ng-transclude="body">ng-transclude-body,{{ name }}</div> <div ng-transclude="footer">ng-transclude-footer,{{ name }}</div> </div>
运行结果
我们的transclude对象定义了如何将多个嵌入点与指令内部的指令嵌入点一一对应,拿'footer': '?transcludeFooter'
来解释一下,footer对应指令模板中的一个嵌入点,transcludeFooter
对应指令元素内部的那个transclude-footer
指令,前面的?
表示这个嵌入点不一定有对应的指令存在。根据运行结果,我做出以下推论:首先指令模板替换(嵌入?)页面中指令所在的元素;然后如果指令的transclude
选项不为false
,则从指令内容中选择指定元素嵌入(替换?)到指令模板中的指定位置,而transclude
对象就是确定对应关系的桥梁;最后如果指令中没有对应关系的其它内容都会对应到ng-transclude
。