点击外部或按下Esc键时关闭Angularjs Bootstrap模态框的调用

26

我在我的项目中使用Angular-ui/bootstrap模态框。

这是我的模态框:

$scope.toggleModal = function () {
    $scope.theModal = $modal.open({
        animation: true,
        templateUrl: 'pages/templates/modal.html',
        size: "sm",
        scope: $scope
    });
}

点击 ESC 按钮或点击模态框外部区域即可关闭模态框,是否有一种方法可以在此时运行函数?我不太确定如何捕获这种关闭事件。

我知道可以通过添加 ng-click="closeModal()" 来手动关闭模态框:

$scope.closeModal = function () {
    $scope.theModal.dismiss('cancel');
};

1
捕获触发器,添加preventDefault(); 添加您想要运行的代码,并以关闭模态命令结束。 - Sven van den Boogaart
6个回答

30

可以的。这会导致一个dismiss事件,在这种情况下,承诺被拒绝。另外,注意$modal.open()方法返回一个具有result属性的对象,该属性是一个承诺。

使用这个承诺,你可以...

//This will run when modal dismisses itself when clicked outside or
//when you explicitly dismiss the modal using .dismiss function.
$scope.theModal.result.catch(function(){
    //Do stuff with respect to dismissal
});

//Runs when modal is closed without being dismissed, i.e when you close it
//via $scope.theModal.close(...);
$scope.theModal.result.then(function(datapassedinwhileclosing){
    //Do stuff with respect to closure
});

你可以使用快捷方式:

 $scope.theModal.result.then(doClosureFn, doDismissFn);

查看参考资料

open方法返回一个模态框实例,该实例具有以下属性:

  • close(result) - 可用于关闭模态框并传递结果的方法
  • dismiss(reason) - 可用于解散模态框并传递原因的方法
  • result - 一个 promise,在模态框被关闭时解决,当模态框被解散时拒绝
  • opened - 一个 promise,在下载内容模板并解析所有变量后,当模态框被打开时解决
  • 'rendered' - 一个 promise,在模态框渲染完成后解决

1
谢谢PSL!这个完美运作,感谢额外的信息。 - bryan
嗨,PSL,你能回答这个问题吗?https://stackoverflow.com/questions/43583136/bootstrap-modal-popup-open-and-close-using-angularjs-not-working - Vinoth
@Vinoth,你应该在你的确定和取消按钮中使用 type="button",因为它们位于表单内部。默认按钮类型是提交,会导致表单提交事件,这就是你看到的页面刷新。或者你也可以在这些方法中获取 $event 并使用 preventDefault() - PSL
@PSL,我尝试了"type="button"",但没有改善。 - Vinoth

25

这个问题比较老,但如果你想在各种关闭操作上添加确认对话框,请将以下代码添加到你的模态实例控制器中:

$scope.$on('modal.closing', function(event, reason, closed) {
    console.log('modal.closing: ' + (closed ? 'close' : 'dismiss') + '(' + reason + ')');
    var message = "You are about to leave the edit view. Uncaught reason. Are you sure?";
    switch (reason){
        // clicked outside
        case "backdrop click":
            message = "Any changes will be lost, are you sure?";
            break;

        // cancel button
        case "cancel":
            message = "Any changes will be lost, are you sure?";
            break;

        // escape key
        case "escape key press":
            message = "Any changes will be lost, are you sure?";
            break;
    }
    if (!confirm(message)) {
        event.preventDefault();
    }
});

我在右上角有一个关闭按钮,它会触发“取消”操作。如果启用了背景,点击背景也会触发取消操作。你可以使用这个功能为不同的关闭事件使用不同的消息。我想分享一下,以便对其他人有所帮助。


我尝试了您提供的解决方案,但对我无效。您能否提供plunker链接?http://plnkr.co/edit/APp2N5?p=preview - Kushal Suthar
@kushalsuthar 有两个原因:你使用了旧版本的angular.js和ui-bootstrap(请参见index.html),并且你需要为你的模态框提供一个专用的控制器。这是更新后的Punker链接:http://plnkr.co/edit/8MThqCxeh9pEf37eBFSB?p=preview - Tiago
实际上我已经得到了那个解决方案。谢谢你的回复。 - Kushal Suthar
嗨,Tiago,你能回答这个问题吗?https://stackoverflow.com/questions/43583136/bootstrap-modal-popup-open-and-close-using-angularjs-not-working - Vinoth

14
你可以使用$modal.open()方法返回的“result”承诺。如下所示:
 $scope.toggleModal = function () {
      $scope.theModal = $modal.open({
          animation: true,
          templateUrl: 'pages/templates/modal.html',
          size: "sm",
          scope: $scope
      });

      $scope.theModal.result.then(function(){
          console.log("Modal Closed!!!");
      }, function(){
          console.log("Modal Dismissed!!!");
      });
 }

你还可以使用以下方式的“result”承诺的“finally”回调函数:

     $scope.theModal.result.finally(function(){
          console.log("Modal Closed!!!");
      });

嗨,Yashika Garg,你能回答这个问题吗?https://stackoverflow.com/questions/43583136/bootstrap-modal-popup-open-and-close-using-angularjs-not-working - Vinoth

1
在我的情况下,当关闭模态框时,我们希望显示一个提示,警告用户这样做将会丢失模态表单中的所有未保存数据。为此,请在模态框上设置以下选项:
var myModal = $uibModal.open({
          controller: 'MyModalController',
          controllerAs: 'modal',
          templateUrl: 'views/myModal.html',
          backdrop: 'static',
          keyboard: false,
          scope: modalScope,
          bindToController: true,
        });

这可以防止在点击外部区域时关闭模态框:
backdrop: 'static'

这可以防止在按下“esc”键时关闭模态框:

keyboard: false

然后在模态控制器中添加自定义的“取消”函数 - 在我的情况下,弹出一个漂亮的警告框,询问用户是否希望关闭模态框:

  modal.cancel = function () {
    $timeout(function () {
      swal({
        title: 'Attention',
        text: 'Do you wish to discard this data?',
        type: 'warning',
        confirmButtonText: 'Yes',
        cancelButtonText: 'No',
        showCancelButton: true,
      }).then(function (confirm) {
        if (confirm) {
          $uibModalInstance.dismiss('cancel');
        }
      });
    })
  };

最后,在模态控制器内添加以下事件监听器:
  var myModal = document.getElementsByClassName('modal');
  var myModalDialog = document.getElementsByClassName('modal-dialog');

  $timeout(function () {
    myModal[0].addEventListener("click", function () {
      console.log('clicked')
      modal.cancel();
    })

    myModalDialog[0].addEventListener("click", function (e) {
      console.log('dialog clicked')
      e.stopPropagation();
    })
  }, 100);

"

"myModal"是您想要在其上调用modal.cancel()回调函数的元素。 "myModalDialog"是模态内容窗口 - 我们停止该元素的事件传播,以便它不会冒泡到"myModal"。

这仅适用于点击模态框外部(也就是单击背景)。按下“esc”键不会触发此回调。

"

0

你可以尝试使用 ng-click="$dismiss()" 替代 ng-click="closeModal()"

。该方法更为简洁。

<button ng-click="$dismiss()">Close</button>

0
我们可以在控制器中像这样调用jquery的“On”事件。 这里的“viewImageModal”是模态弹出窗口的ID。
constructor($scope: AuditAppExtension.IActionPlanScope, dataSvc: ActionPlanService, Upload, $timeout, $mdToast: any) {

            $('#viewImageModal').on('shown.bs.modal', function (e) {
                console.log("shown", e);

                $scope.paused = false;
                $modal.find('.carousel').carousel('cycle');
            });

            $('#viewImageModal').on('hide.bs.modal', function (e) {
                console.log("hide", e);

                return true;
            });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接