【问题标题】:Hot to cancel the opening of a modal window in angularjs热取消在angularjs中打开模态窗口
【发布时间】:2014-02-14 10:43:17
【问题描述】:

在我的 Angular 应用程序中,我有一个网格,上面有一个按钮来显示有关当前行的详细信息。我通过 $http 将详细数据获取到 sql 数据库,当正确获取数据时,我打开一个模式窗口以显示详细信息。我想要的是防止在出现错误时打开模式窗口(例如,http 状态代码未找到)。我的代码如下:

var modalInstance = $modal.open({
    templateUrl: '/Scripts/app/views/konto/kontoCrud.htm',
    backdrop: true,
    keyboard: true,
    windowClass: 'szpModal fade in',
    controller: 'KontoCrudCtrl',
    resolve: {
        konto: function () {
            if ($scope.mode === "new") {
                return { mode: mode,
                    sifra: "",
                    naziv: ""
                };
            } else {
                //console.log($scope.selectedItem);
                var result = kontoFactory.getKonto($scope.selectedItem[0].id);
                console.log(result);
                if (result.status === "OK") {
                    return result;
                } else {
                    toastr.error("Error fetching data!");
                    **// HERE I WANT TO CANCEL THE OPENING OF THE WINDOW AS 
                    // THE RECORD WAS NOT FOUND**
                }

            }
        }
    }

【问题讨论】:

  • 此时可以访问用ui-bootstrap modal实现的原生$scope.close()了吗?
  • @glepetre。我已经尝试过了,但出现以下错误:TypeError: Object # has no method 'close'。我还尝试了 $scope.$close,因为在 angular-ui 中,这是关于模态窗口的说明:此外,与模态内容相关的范围增加了 2 种方法: * $close(result) * $dismiss(reason) 这些方法无需创建专用控制器即可轻松关闭模式窗口。我不能让它工作,只是不知道该怎么做。
  • 有什么永久的解决方案吗?下面提到的所有答案都可以解决..

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


【解决方案1】:

这不是您遇到的问题的解决方案,而是一种解决方法。

在点击按钮时,首先调用工厂方法,如果可以,则打开模态,否则不要。

var result = kontoFactory.getKonto($scope.selectedItem[0].id);
console.log(result);
if (result.status === "OK") {
    var modalInstance = $modal.open({
    templateUrl: '/Scripts/app/views/konto/kontoCrud.htm',
    backdrop: true,
    keyboard: true,
    windowClass: 'szpModal fade in',
    controller: 'KontoCrudCtrl',
    resolve: {
        konto: function () {
            if ($scope.mode === "new") {
                return { mode: mode,
                    sifra: "",
                    naziv: ""
                };
            } else {
                return result;
            }
        }
    }
});
} else {
    toastr.error("Error fetching data!");
}

【讨论】:

  • 不能那样做。我使用 resolve 属性在窗口打开之前加载数据,以避免页面闪烁。
  • 您可以从 http 调用返回一个回调,并在该回调中打开模式。这不会让您闪烁页面。
  • 您的解决方案确实有效,但我认为这并不完全符合我的想法。所以,正确的答案是你的。
【解决方案2】:

换个角度思考:

var openModal = function(konto){

    var modalInstance = $modal.open({
        templateUrl: '/Scripts/app/views/konto/kontoCrud.htm',
        backdrop: true,
        keyboard: true,
        windowClass: 'szpModal fade in',
        controller: 'KontoCrudCtrl',
        resolve: {
            konto: function () {
                return konto;
            }
        }
}    
 if ($scope.mode === "new") {
    openModal({ mode: mode,
            sifra: "",
            naziv: ""
        });

    } else {
        //console.log($scope.selectedItem);
        var result = kontoFactory.getKonto($scope.selectedItem[0].id);
        console.log(result);
        if (result.status === "OK") {
            openModal(result);
        } else {
            toastr.error("Error fetching data!");
            // THE RECORD WAS NOT FOUND**
        }

    }

【讨论】:

    【解决方案3】:

    这就是我所做的,我为模态定义了一个小控制器(我也在我自己的控制器中使用模态)。适用于您的案例:

    var modalInstance = $modal.open({
      templateUrl: '/Scripts/app/views/konto/kontoCrud.htm',
      backdrop: true,
      keyboard: true,
      windowClass: 'szpModal fade in',
      //change the controller
      controller: function($scope, $modal) {
        $scope.closeModal = function() {
          $scope.$close();
        };
      },
      // here I used modalInstance.result.then(function() {});
      // but resolve should work too
      resolve: {
        konto: function () {
          if ($scope.mode === "new") {
            return { mode: mode,
                    sifra: "",
                    naziv: ""
            };
          } else {
            //console.log($scope.selectedItem);
            var result = kontoFactory.getKonto($scope.selectedItem[0].id);
            console.log(result);
            if (result.status === "OK") {
              return result;
            } else {
              toastr.error("Error fetching data!");
              // call you close function
              $scope.closeModal();
            }
          }
        }
      };
    

    【讨论】:

    • 运行代码时出现此错误:TypeError: Object # has no method 'closeModal'。显然方法只在子范围内可见。
    • 哪个子作用域?我错过了一些东西。如果你写controller: function(){...} 没有args,你会收到错误吗?
    【解决方案4】:

    假设你工厂的getKonto函数是这样的:

    function getKonto(id) {
      return $http.get('/youService/getKonto/' + id).then(function (response) {
         if (response.status === 200) {
             return response.data;
         } else {
             throw new Error("Something happened!");
         }
      });
    }
    

    然后在你的 else 语句中你应该做这样的事情:

    kontoFactory.getKonto($scope.selectedItem[0].id)
       .then(function (result) {
          //OPEN YOUR MODAL HERE
       })
       .catch (function (error) {
          //PROVISION TO SHOW YOUR ERROR HERE
       });
    

    【讨论】:

    • 是的,我最后就是这样做的,但是我想在启动模态窗口时使用“resolve”方法。
    猜你喜欢
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多