当指令模板的各个部分存在各自的交叉内容时,替换它们
Replacing parts of directive template when their respective transclusion content is present
我正在尝试执行以下操作:
如果我添加<my-custom-directive></<my-custom-directive>
它应该扩展到
<div class="my-custom-container">
<label class="my-custom-label">Fallback</label>
<input class="my-custom-input"/>
</div>
这可以通过在DDO中将上述设置为CCD_ 2和CCD_。
如果我在HTML中添加以下内容:
<my-custom-directive>
<my-custom-label class="users-custom-class"><span>Custom content</span><my-custom-label>
</<my-custom-directive>
它应该扩展到
<div class="my-custom-container">
<label class="my-custom-label users-custom-class"><span>Custom content</span></label>
<input class="my-custom-input"/>
</div>
这意味着,如果用户想要提供自定义的<label>
、<input>
等,我们使用transclusion,transclusion的内容将替换原始模板中的相应槽,类似于replace:true
指令将如何用其模板替换自身。
我无法组合replace
和transclusion功能。
到目前为止,我所拥有的(某些工作状态)如下:
angular.module('test', [])
.directive('transTest', function() {
return {
transclude: {
lab: '?labelTest',
inp: '?inputTest'
},
replace: true,
template: '<div class="container"><label ng-transclude="lab">Fallbacl label</label><input type="text" placeholder="fallback" ng-transclude="inp"></div>',
link: function(scope, element, attrs, ctrl, transclude) {
console.log(transclude())
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.js"></script>
<div ng-app="test">
<div trans-test class="test">
<label-test>test label</label-test>
<input-test>test input</input-test>
</div>
</div>
正如你所看到的,transcluded内容进入了包含translate元素的内部,而不是替换它。我已经阅读了源代码注释、文章,还检查了ui bootstrap accordon的实现,并尝试了transclude:'element'
,但它在DOM中只留下了一个注释。
transclusion、replace等是我发现的可用选项,它们提供了与我试图实现的功能类似的功能。但他们似乎打得不好。如果可能的话,实现这种角度功能的正确方法是什么。。?
看来我终于成功了。该解决方案由两部分组成:
-
使用类似于回退(默认)的模板为transclude slot元素定义指令。
这样做的主要原因是在DDO中设置
replace:true
时,利用angular的内置功能将属性复制到templates根元素。我不想在链接功能中手动操作
另一个原因是,它允许您添加额外的功能,如默认模板中不需要的交叉 -
第二步是不在模板中定义
ng-transclude
指令,而是使用传递给link
的transclude
函数来访问各个插槽的已包含内容,并在存在已包含内容的情况下用已包含内容替换相应元素(使用transclude.isSlotFilled()
)
好吧,这不容易让我理清思路,也不容易解释。希望下面的演示能比文字更好地解释它:
angular.module('test', [])
.directive('transTest', function() {
return {
replace: true,
transclude: {
lab: '?labelTest',
inp: '?inputTest'
},
template: '<div class="test-parent"><label class="fallback-label">Fallback </label><br><input type="text" class="fallback-input"></div>',
link: function(scope, element, attrs, ctrl, transclude) {
if (transclude.isSlotFilled('lab')) {
var label = transclude(angular.noop, null, 'lab');
element.find('label').replaceWith(label);
}
if (transclude.isSlotFilled('inp')) {
var input = transclude(angular.noop, null, 'inp');
element.find('input').replaceWith(input);
}
}
}
}).directive('labelTest', function($compile) {
return {
template: '<label class="fallback-label ng-transclude">Fallback </label>',
replace: true,
transclude: true
}
}).directive('inputTest', function($compile) {
return {
template: '<input type="text" class="fallback-input">',
replace: true
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.js"></script>
<div ng-app="test">
<div trans-test class="test">
<label-test class="custom-label">Custom content</label-test>
<input-test class="custom-input" placeholder="custom"></input-test>
</div>
<br>
<br>
<div trans-test class="test">
</div>
</div>
您可能正在寻找一个更优雅的解决方案,但您可以使用指令的控制器$transclude
函数来了解transclusion-slot
是否已填充。
controller: function($transclude, $scope) {
$scope.fallback = !$transclude.isSlotFilled('lab');
然后,使用这些信息构建模板。
template: '<div class="container">'
<label ng-if="fallback === true">Fallback label</label>'
<div ng-if="fallback === false" ng-transclude="lab"></div>'
但是,如果您能够完全定义要传输的内容,
<label-test>
<label>test label</label>
</label-test>
替换目标内容可能比替换整个元素更有意义:
template: '<div class="container">'
<div ng-transclude="lab">'
<label>Fallback label</label>'
</div>'
下面是一个展示两种方法的plunker:http://plnkr.co/edit/EEq5vovFrSW7kG81yWuf?p=preview
- 指令的模板必须只有一个根元素:With restrict E&替换true
- 无法用tr替换表中的指令
- 当指令模板的各个部分存在各自的交叉内容时,替换它们
- AngularJS指令模板ng重复有趣的替换
- AngularJS SVG 指令,不推荐使用替换
- 如何实现 Angular 指令来替换元素,但仅限于某些情况
- 替换指令中的值而不替换整个指令
- 为什么将 ng-select 替换为自定义指令会导致$http请求不会每隔一段时间发送一次
- 正则表达式在指令中替换为 html 标记
- 控制 AngularJS 如何替换 ngInclude 或自定义指令
- 如何使用带有替换的模板覆盖/补充指令中的ng类:true
- 为什么“替换:真”在 AngularJS 指令中被弃用
- 用于替换用户输入中的字符的角度指令
- 如何替换Angular指令中不推荐使用的替换属性
- 替换“;templateUrl”:路径带有“;模板”:使用gump的角度指令的内容
- 用于替换文本的 Angularjs 指令
- 在指令's链接中替换angular元素html
- 如何让angular指令包含&替换另一个指令
- AngularJS指令:将属性值直接替换到模板中
- SVG的角度替换指令(结果在DOM中,但未显示)