我有两个元素指令collection
和element
,应该这样使用:
<collection>
<element/>
<element/>
</collection>
他们有模板:
collection.html
<header>header</header>
<div><ul>...</ul></div>
<footer>footer</footer>
element.html
<p>element</p>
应该用什么代替collection.html
中的...
来用<li>..</li>
包裹每个element
?
表达结果
<header>header</header>
<div>
<ul>
<li><p>element</p></li>
<li><p>element</p></li>
</ul>
</div>
<footer>footer</footer>
更新
在回顾问题背后的任务时,似乎element
标记实际上是嵌套HTML的包装器,这简化了事情。因此,我添加了一个答案,描述了如何使用2级嵌套transclusion。
ng-transclude
允许您在模板化指令中嵌套内容,这样您就可以在指令编译阶段操作transcluded元素。
在这种情况下,您需要使用transclude: 'element'
来跨接整个collection
元素。这是因为您需要以结构化的方式对子元素进行操作(使用transclude: true
提供了所有子节点的平面阵列,而这在这里不起作用(。
.directive('collection', function(){
return {
transclude: 'element',
使用transclusion时,指令的编译函数中会有一个transclude
函数可用。此函数传递一个参数clone
,该参数为您提供了已传输内容的克隆。使用transclude: 'element
时,整个指令元素将从页面中删除。这需要您稍后将其添加回。
compile: function(element, attrs, transclude) {
return {
pre: function(scope, element) {
transclude(scope, function(clone){
要开始操作我们将添加回来的内容,请迭代克隆的子元素,使用jqLite wrap
函数用列表项标记包装它们:
angular.forEach(clone.children(), function(el){
var el = angular.element(el);
el.replaceWith(el.wrap('<li></li>'));
});
然后从存储在传递到compile/link:的元素中的HTML创建并存储一个新的jqLite元素
var html = angular.element(element.html());
使用jqLite find
选择其内部的ul
元素,并使用append
修改后的交叉克隆:
html.find('ul').append(clone);
最后用成品代替编译后的CCD_ 19
element.replaceWith(html);
你会在这里找到一个工作的Plunker。
当我问这个问题时,我似乎没有完全理解任务。
但当我看到@MarcKline的回答时,我对我的问题的有效性产生了怀疑,因为规则">如果你不能在没有角度jQuery的情况下完成它,你可能做错了"。
因此,我改变了element
标签的概念——现在它们也是容器,它们嵌套了html,也可以作为包装器使用。所以我的最终解决方案是:
angular.module('myApp', [])
.controller('MyController', function($scope){})
.directive('collection', function($compile){
return {
transclude: 'true',
restrict: 'E',
template: '<header>header</header><div><ul ng-transclude></ul></div><footer>footer</footer>',
}
})
.directive('element', function(){
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<li><div ng-transclude></div></li>'
}
});
<body ng-app="myApp" ng-controller="MyController">
<collection>
<element>inner1</element>
<element>inner2</element>
<element>inner3</element>
</collection>
</body>
plunkr