Javascript 单击外部/ esc 时,Angularjs Bootstrap 模态结束调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30356844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:03:27  来源:igfitidea点击:

Angularjs Bootstrap modal closing call when clicking outside/esc

javascriptangularjsangular-uiangular-ui-bootstrap

提问by bryan

I am using the Angular-ui/bootstrapmodal in my project.

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

Here is my modal:

这是我的模态:

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

One is able to close the modal by clicking the ESCbutton or clicking outside the modal area. Is there a way to run a function when this happens? I am not quite sure how to catch the sort of closing.

可以通过单击ESC按钮或在模态区域外单击来关闭模态。发生这种情况时,有没有办法运行函数?我不太确定如何捕捉这种关闭。

I know that I can manually dismiss a modal by having a ng-click="closeModal()"like this:

我知道我可以通过这样的方式手动关闭模态ng-click="closeModal()"

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

回答by PSL

Yes you can. It causes a dismiss event and the promise is rejected in that case. Also, note that the $modal.open()method returns an object that has a resultproperty that is a promise.

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

With the promise you can...

有了承诺,您可以...

//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
});

as a shortcut you could write:

作为快捷方式,您可以编写:

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

See ref

见参考

The open method returns a modal instance, an object with the following properties:

  • close(result) - a method that can be used to close a modal, passing a result
  • dismiss(reason) - a method that can be used to dismiss a modal, passing a reason
  • result - a promise that is resolved when a modal is closed and rejected when a modal is dismissed
  • opened - a promise that is resolved when a modal gets opened after downloading content's template and resolving all variables 'rendered' - a promise that is resolved when a modal is rendered.

open 方法返回一个模态实例,一个具有以下属性的对象:

  • close(result) - 一种可用于关闭模态并传递结果的方法
  • 解雇(原因) - 一种可用于关闭模态,传递原因的方法
  • 结果 - 在模态关闭时解决并在模态被解除时拒绝的承诺
  • opens - 在下载内容模板并解析所有变量“渲染”后打开模态时解析的承诺 - 在呈现模态时解析的承诺。

回答by Tiago

Old question, but if you want to add confirmation dialogs on various close actions, add this to your modal instance controller:

老问题,但如果您想在各种关闭操作上添加确认对话框,请将其添加到您的模态实例控制器中:

$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();
    }
});

I have a close button on the top right of mine, which triggers the "cancel" action. Clicking on the backdrop (if enabled), triggers the cancel action. You can use that to use different messages for various close events. Thought I'd share in case it's helpful for others.

我的右上角有一个关闭按钮,它会触发“取消”操作。单击背景(如果启用),会触发取消操作。您可以使用它为各种关闭事件使用不同的消息。以为我会分享,以防对其他人有帮助。

回答by Yashika Garg

You can use the "result" promise returned by $modal.open() method. As bellow:

您可以使用 $modal.open() 方法返回的“结果”承诺。如下:

 $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!!!");
      });
 }

Also you can use "finally" callback of "result" promise as below:

您也可以使用“result”承诺的“finally”回调,如下所示:

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

回答by Maegan Womble

In my case, when clicking off the modal, we wanted to display a prompt warning the user that doing so would discard all unsaved data in the modal form. To do this, set the following options on the modal:

在我的例子中,当点击模态时,我们想显示一个提示警告用户这样做会丢弃模态表单中所有未保存的数据。为此,请在模态上设置以下选项:

var myModal = $uibModal.open({
          controller: 'MyModalController',
          controllerAs: 'modal',
          templateUrl: 'views/myModal.html',
          backdrop: 'static',
          keyboard: false,
          scope: modalScope,
          bindToController: true,
        });

This prevents the modal from closing when clicking off:

这可以防止模态在单击关闭时关闭:

backdrop: 'static'

And this prevents the modal from closing when hitting 'esc':

这可以防止模式在点击“esc”时关闭:

keyboard: false

Then in the modal controller, add a custom "cancel" function - in my case a sweet alert pops up asking if the user wishes to close the modal:

然后在模态控制器中,添加一个自定义的“取消”功能 - 在我的情况下,会弹出一个甜蜜的警报,询问用户是否希望关闭模态:

  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');
        }
      });
    })
  };

And lastly, inside the modal controller, add the following event listeners:

最后,在模态控制器中,添加以下事件侦听器:

  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" is the element you want to call the modal.cancel() callback function on. "myModalDialog" is the modal content window - we stop the event propagation for this element so it won't bubble up to "myModal".

“myModal”是您要调用 modal.cancel() 回调函数的元素。“myModalDialog”是模态内容窗口 - 我们停止此元素的事件传播,因此它不会冒泡到“myModal”。

This only works for clicking off the modal (in other words clicking the backdrop). Hitting 'esc' will not trigger this callback.

这仅适用于单击模式(即单击背景)。点击 'esc' 不会触发这个回调。

回答by Felipe Anselmo

Instead of ng-click="closeModal()"you can try ng-click="$dismiss()"

而不是ng-click="closeModal()"你可以尝试ng-click="$dismiss()"

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

回答by Devnarayan Nagar

We can call jquery 'On' event as well in the controller like this. here "viewImageModal" is the id of modal popup.

我们也可以像这样在控制器中调用 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;
            });
}