【问题标题】:AngularJS modal with promise unhandled exception带有未处理异常的 AngularJS 模态
【发布时间】:2018-02-11 03:46:55
【问题描述】:

我的控制器中有一个函数,该函数从需要布尔响应的第三方库调用。该函数打开一个模式(定义为服务)以获取用户的响应并将其作为承诺返回。但是,当在模式上按下关闭时,我在控制台中收到错误

可能未处理的拒绝:取消

我花了几个小时试图用各种方法解决这个问题,但在返回真/假时无法消除错误。有人可以帮忙吗?

服务

angular.module('app')
.service("ModalService", function ($uibModal) {

var modalDefaults = {
    backdrop: true,
    keyboard: true,
    modalFade: true,
    templateUrl: '/app/components/shared/modal.html'
};

var modalOptions = {
    closeButtonText: 'No',
    actionButtonText: 'Yes',
    headerText: 'Title',
    bodyText: 'Are you sure you wish to do this?'
};

this.showModal = function (customModalDefaults, customModalOptions) {
    if (!customModalDefaults) {
        customModalDefaults = {};
    }
    customModalDefaults.backdrop = 'static';
    return this.show(customModalDefaults, customModalOptions);
};

this.show = function (customModalDefaults, customModalOptions) {
    // Create temp objects to work with since we're in a singleton service
    var tempModalDefaults = {};
    var tempModalOptions = {};

    // Map angular-ui modal custom defaults to modal defaults defined in service
    angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);

    // Map modal.html $scope custom properties to defaults defined in service
    angular.extend(tempModalOptions, modalOptions, customModalOptions);

    if (!tempModalDefaults.controller) {
        tempModalDefaults.controller = function ($scope, $uibModalInstance) {

            $scope.modalOptions = tempModalOptions;

            $scope.modalOptions.ok = function (result) {
                $uibModalInstance.close(true);
            };

            $scope.modalOptions.close = function (result) {
                $uibModalInstance.dismiss('cancel');
            };
        }
    }

    return $uibModal.open(tempModalDefaults).result;
};

});

控制器功能

this.onRemovingLabel = function($tag) { 
    var modalOptions = {
        closeButtonText: 'Cancel',
        actionButtonText: 'Delete',
        headerText: 'Delete Label: ' + $tag.name,
        bodyText: 'By removing this label all marked tags in the the dataset will be deleted. Do you wish to continue?'
    };

    return ModalService.showModal({}, modalOptions);
}

从 HTML 调用函数

<tags-input ... on-tag-removing="tc.onRemovingLabel($tag)">

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    为避免使用deferred anti-pattern,只需返回修改后的promise:

    this.onRemovingLabel = function($tag) { 
            var modalOptions = {
                closeButtonText: 'Cancel',
                actionButtonText: 'Delete',
                headerText: 'Delete Label: ' + $tag.name,
                bodyText: 'By removing this label all marked tags in the the dataset will be deleted. Do you wish to continue?'
            };
    
            ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶ 
    
            ̲r̲e̲t̲u̲r̲n̲ ModalService.showModal({}, modalOptions) ̶.̶t̶h̶e̶n̶(̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶(̶r̶e̶s̶u̶l̶t̶)̶ ̶{̶    
                ̶d̶e̶f̶e̶r̶.̶r̶e̶s̶o̶l̶v̶e̶(̶r̶e̶s̶u̶l̶t̶)̶;̶
            ̶}̶)̶ .catch(function(result) {
                // Modal cancelled, this prevents an unhandled exception error on the console.
            });
    
            ̶r̶e̶t̶u̶r̶n̶ ̶d̶e̶f̶e̶r̶.̶p̶r̶o̶m̶i̶s̶e̶;̶
    }
    

    .catch 处理函数省略return statement 时,它会返回一个值undefined,这会将被拒绝的承诺转换为一个成功解决且值为undefined 的承诺。

    return ModalService.showModal({}, modalOptions)
      .catch(function(result) {
        return false;
    });
    

    这会将被拒绝的承诺转换为返回result的成功承诺。

    有关详细信息,请参阅You're Missing the Point of Promises

    【讨论】:

    • 谢谢@georgeawg。我不太清楚你修改过的代码,你是说先捕获,然后在捕获 defer.resolve(result) 内?
    • 这会返回取消,而不是第 3 方库需要的 false。
    【解决方案2】:

    我最终用

    解决了这个问题
    this.onRemovingLabel = function($tag) { 
            var modalOptions = {
                closeButtonText: 'Cancel',
                actionButtonText: 'Delete',
                headerText: 'Delete Label: ' + $tag.name,
                bodyText: 'By removing this label all marked tags in the the dataset will be deleted. Do you wish to continue?'
            };
    
            var defer = $q.defer();
    
            ModalService.showModal({}, modalOptions).then(function (result) {
                defer.resolve(result);
            }).catch(function(result) {
                // Modal cancelled, this prevents an unhandled exception error on the console.
            });
    
            return defer.promise;
    }
    

    【讨论】:

    • 这是一个deferred anti-pattern,当showModal 函数返回一个被拒绝的promise 时,它​​会挂起并造成内存泄漏。
    猜你喜欢
    • 1970-01-01
    • 2011-11-19
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 2016-02-11
    • 1970-01-01
    相关资源
    最近更新 更多