根据角度开发人员指南:
transclude - 编译元素的内容并使其可用于指令。
内容编译时是否可以更改?出于性能原因,我想将内容传递给我想用正确的范围(父级)编译的指令,但只有当/如果某个事件发生时。那可能吗?如果没有,有没有办法我可以以不同的方式做到这一点?
根据角度开发人员指南:
transclude - 编译元素的内容并使其可用于指令。
内容编译时是否可以更改?出于性能原因,我想将内容传递给我想用正确的范围(父级)编译的指令,但只有当/如果某个事件发生时。那可能吗?如果没有,有没有办法我可以以不同的方式做到这一点?
我这样做是为了确保在事件发生之前不会将嵌入的内容插入到 DOM 中,尽管我不能 100% 确定实际编译何时发生。它看起来像这样(使用 jQuery):
app.directive('thumbnail', function() {
return {
replace: true,
transclude: true,
template: "<div><a class='clicker'>Click to show.</a>\n" +
"<div class='placeholder'></div></div>",
controller: function($scope, $transclude, $element) {
$element.find('.clicker').once('click', function() {
$(this).hide();
var clone = $transclude();
$element.find('.placeholder').append(clone);
});
})
};
});
<div thumbnail>
<div expensive-dom-stuff-here></div>
</div>
以防其他人和我有同样的问题,我已经包含了我所做的一个简化版本。该指令是包含嵌入内容的可展开/可折叠部分。出于性能原因,它不会编译嵌入的内容,直到需要它,在这种情况下,只有当第一次扩展该部分时。展开后,内容成为 DOM 的一部分,不再需要编译/转入。该指令的大部分内容应该非常基本且易于解释,但控制器属性是我过去没有使用过的。
您还会注意到我没有使用 compile 或 link 属性。对于这个基本指令,当指令本身被编译时,我不需要进行任何 DOM 操作,因此将所有内容都粘贴在控制器中就可以了。澄清一下,指令中运行的顺序是编译、链接,然后是控制器中的任何内容。控制器使您可以访问可以在编译/链接函数中使用的所有内容,因此我将所有内容放在那里是为了简单、可读性和可维护性。
我希望这可以帮助像我这样的其他菜鸟。很高兴听到您的评论。
uiComponentsModule.directive('CollapsibleSection', ['$timeout', function($timeout) {
return {
restrict: 'A',
replace: true,
transclude: true,
scope: {
sectionTitle:'@',
sectionId:'@',
startExpanded:'@'
},
template: '<div>' +
'<div ng-click="toggle()" class="collapsible-section-header">' +
'<span class="collapsible-section-title"</span>' +
'</div>' +
'<div class="collapsible-section" ng-show="isExpanded">'+
'<div class="transclude-me"></div>'+
'<div class="div-clear"></div>'+
'</div>' +
'</div>',
controller: ['$scope', '$element', '$attrs', '$transclude', function (scope, element, attrs, $transclude) {
scope.isExpanded = false;
scope.isLoaded = false;
scope.toggle = function(){
if(scope.isExpanded)
scope.close();
else
{
scope.open();
}
};
scope.showTransclude = function(){
$transclude(function(clone) {
element.find(".transclude-me").append(clone);
});
};
scope.open = function(){
scope.isExpanded = true;
if(!scope.isLoaded)
{
scope.showTransclude();
scope.isLoaded = true;
}
};
scope.close = function(){
scope.isExpanded = false;
};
}]
}
}