【问题标题】:Angularjs Bootstrap modal closing call when clicking outside/esc单击外部/esc时Angularjs Bootstrap模式关闭调用
【发布时间】:2015-05-20 17:46: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');
};

【问题讨论】:

  • 捕获触发器,添加preventDefault();使用关闭模式命令添加要运行的代码。

标签: javascript angularjs angular-ui angular-ui-bootstrap


【解决方案1】:

是的,你可以。它会导致关闭事件,并且在这种情况下,承诺会被拒绝。另请注意,$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);

See ref

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

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

【讨论】:

  • 感谢 PSL!这很完美,感谢您提供额外的信息。
  • 嗨,PSL,你能回答这个问题吗stackoverflow.com/questions/43583136/…
  • @Vinoth 您应该使用type="button" 作为您的确定和取消按钮,因为它们位于表单内。默认按钮类型是提交,将导致表单发布事件,这就是您所看到的页面刷新。或者,您也可以在这些方法上获取 $eventpreventDefault()
  • @PSL,我试过那个“type="button",但没有改善
【解决方案2】:

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

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

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

【讨论】:

【解决方案3】:

您可以使用 $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!!!");
      });
 }

您也可以使用“结果”承诺的“最终”回调,如下所示:

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

【讨论】:

【解决方案4】:

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

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' 不会触发此回调。

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-11
        • 2019-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多