javascript - 包含 ng-template 的指令中的 Angular 嵌入(通用 Confirm Modal)

标签 javascript angularjs modal-dialog angular-bootstrap transclusion

你好,我正在努力创建基于 angular-bootstrap Modal 指令的通用确认指令。

我找不到一种方法将我的内容嵌入到用于模态构造的 ng-template 中,因为 ng-transclude 指令未被评估,因为它是 ng 的一部分-template 在执行 $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只有在单击“open confirm modal #2”按钮时,我才等着看“Are you sure ? (modal #2)”。

最佳答案

ui-bootstrap modal 仅支持 templatetemplateUrl 作为指定内容的方式。无论内容如何被检索,它都会被编译并链接到由 $modal(或者更确切地说,内部 $modalStack)服务提供的范围。

所以,至少,像那样,没有办法提供嵌入。

一种解决方法是嵌入一个占位符指令,该指令将附加嵌入的 DOM - 但嵌入的 DOM,因为它来自不同于模态的位置,需要以某种方式移交给该占位符指令。您已经将 content 作为注入(inject)的解析参数。我将在稍作修改后使用它 - 我将传递实际的 DOM,而不是解析后的 H​​TML。

所以,在高层次上:

.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 函数中(省略不相关的属性):

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...
}

最后,在模态的实际模板中:

<div class="modal-body">
    <div confirm-popup-transclude="template"></div>
</div>

Your forked plunker

关于javascript - 包含 ng-template 的指令中的 Angular 嵌入(通用 Confirm Modal),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29305161/

相关文章:

javascript - Twitter Bootstrap 表单。如何捕获表单中输入的值?

javascript - 节点标签不工作 d3 v5

javascript - 如何使用 angularjs 在 html 中索引变量

ios - 模态视图在关闭时更改我的选项卡

javascript - 在 chrome 扩展内容脚本中包含 ttf 文件

javascript - 根据条件删除数组元素

javascript - 如何验证AngularJS中的3个复选框中是否至少选中了一个复选框

javascript - Mongoose 在插入文档时调用字段的函数

javascript - 无法从我的 javascript 函数获取值

javascript - 单击按钮时飞入内容框?