在含有NG-模板的指令角transclude(通用确认莫代尔) [英] Angular transclude in a directive containing a ng-template (generic Confirm Modal)

查看:228
本文介绍了在含有NG-模板的指令角transclude(通用确认莫代尔)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我在创建基于角引导模态指令,一个通用的确认指令挣扎。

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 )的服务。

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>

你分叉plunker

这篇关于在含有NG-模板的指令角transclude(通用确认莫代尔)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆