在含有NG-模板的指令角transclude(通用确认莫代尔) [英] Angular transclude in a directive containing a ng-template (generic Confirm Modal)
问题描述
您好,我在创建基于角引导模态指令,一个通用的确认指令挣扎。
Hello I'm struggling while creating a generic confirmation directive based on angular-bootstrap Modal directive.
我无法找到一个方法来transclude我在使用的模式建设NG-模板内容,因为 NG-transclude
指令不评估,因为它的一部分一个的NG-模板
在执行时加载之后 $ modal.open()
:
I can't find a way to transclude my content in the ng-template used for the modal construction because the ng-transclude
directive isn't evaluated since it's part of a ng-template
loaded afterward when executing $modal.open()
:
index.html的(指令插入):
<confirm-popup
is-open="openConfirmation"
on-confirm="onPopupConfirmed()"
on-cancel="onPopupCanceled()"
>
Are you sure ? (modal #{{index}})
confirmPopup.html(指令模板):
<script type="text/ng-template" id="confirmModalTemplate.html">
<div>
<div class="modal-header">
<h3>Confirm ?</h3>
</div>
<div class="modal-body">
{{directiveTranscludedContent}} // ng-transclude do not work here
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<button class="btn btn-primary" ng-click="ok()">Validate</button>
</div>
</div>
</script>
confirmPopup.js(指令JS):
.directive('confirmPopup', [
function() {
return {
templateUrl: 'confirmPopup.html',
restrict: 'EA',
replace: true,
transclude: true,
scope: {
isOpen: '=',
confirm: "&onConfirm",
cancel: "&onCancel"
},
controller: ['$scope', '$element', '$modal', '$transclude', '$compile', function($scope, $element, $modal, $transclude, $compile) {
// watching isOpen attribute to dispay modal when needed
$scope.$watch(
function() {
return $scope.isOpen;
},
function(newValue) {
if (newValue === true) {
openModal();
} else {
// if a modal is already dispayed : the modal must be canceled/confirmed by the user
// else (if no modal is dispayed), then do nothing
}
}
);
// open modal function
// create / register ok/cancel callbacks
// and open modal
// all on one shot
function openModal() {
$modal.open({
templateUrl: 'confirmModalTemplate.html',
controller: ['$scope', '$modalInstance', 'content', function($scope, $modalInstance, content) {
$scope.directiveTranscludedContent = content;
$scope.ok = function() {
$modalInstance.close();
};
$scope.cancel = function() {
$modalInstance.dismiss();
};
}],
resolve: {
content: function() {
return $transclude().html();
//return $compile($transclude().contents())($scope);
},
}
})
.result.then(
// modal has been validated
function() {
$scope.confirm();
},
// modal has been dismissed
function() {
if ($scope.cancel) {
$scope.cancel();
}
}
);
};
}]
};
}
]);
如果这还不够清楚,看到这个 PLUNKER 在那里我等着看你确定吗?(模态2)
仅在打开时确认模#2时,点击
按钮。
If it's not clear enough, see this PLUNKER where I'm waiting to see "Are you sure ? (modal #2)
" only when clicking on the "open confirm modal #2
" button.
推荐答案
UI的引导模式仅支持两种模板
或 templateUrl
,以此来指定内容。然而,内容检索,它被编译并通过 $模式
(或者说,内部 $ modalStack $ C对所提供的范围链接$ C>)的服务。
ui-bootstrap modal only supports either template
or templateUrl
as a way to specify the content. However the content is retrieved, it is compiled and linked against the provided scope by the $modal
(or rather, the internal $modalStack
) service.
因此,至少,这样,也没有办法提供transclusion
So, at least, like that, there is no way to provide transclusion.
方法之一左右,将是嵌入的占位符指令,将追加transcluded DOM - 但transcluded DOM,因为它是从比模式不同的位置来了,需要交给不知何故该占位符指令。你已经有了内容
作为注入的决心参数。我将使用稍加修改 - 我将通过实际的DOM,而不是解析的HTML
One way around, would be to embed a placeholder directive that would append the transcluded DOM - but the transcluded DOM, since it's coming from a location different than the modal, needs to be handed over somehow to that placeholder directive. You already have the content
as an injected resolve parameter. I will use that with slight modification - I will pass the actual DOM, not the parsed HTML.
因此,在一个高级别
So, at a high-level:
.directive("confirmPopupTransclude", function($parse){
return {
link: function(scope, element, attrs){
// could have been done with "=" and isolate scope,
// but avoids an unnecessary $watch
var templateAttr = attrs.confirmPopupTransclude;
var actualTemplateDOM = $parse(templateAttr)(scope);
element.append(actualTemplateDOM);
}
};
})
和,在 openModal
函数(忽略不相关的属性):
And, in the openModal
function (omitting unrelated properties):
function openModal{
$modal.open({
controller: function($scope, content){
$scope.template = content;
// etc...
},
resolve: {
content: function(){
var transcludedContent;
$transclude(function(clone){
transcludedContent = clone;
});
return transcludedContent; // actual linked DOM
},
// etc...
}
最后,在用于模态实际的模板:
Finally, in the actual template for the modal:
<div class="modal-body">
<div confirm-popup-transclude="template"></div>
</div>
这篇关于在含有NG-模板的指令角transclude(通用确认莫代尔)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!