Angular取消删除确认时如何返回闭包或处理无闭包返回场景
Angular删除功能取消弹窗报错修复
问题现象
开发AngularJS项目删除功能时,用户确认删除后的流程运行正常,但如果用户在确认弹窗点击「取消」,程序会抛出如下错误:
Wizard's bound 'deleteAction' must return a closure. undefined
原有逻辑代码
删除按钮点击处理逻辑:
$scope.deleteButtonClick = function () { if ($scope.hasRemove()) { $scope.deleting = true; //Fetch the promise and add our own state management to it var promise = $scope.removeAction(); // this remove action calls the below 'remove' function if (!promise.then) { throw "Wizard's bound 'deleteAction' must return a closure." } promise.then(function () { $scope.deleting = false; }, function () { $scope.deleting = false; }); } };
绑定的删除处理函数:
$scope.remove = function () { if (confirm("Confirm Delete?")){ var data = {}; data.id = EventService.event.id; // delete return $http.post('/admin/deleteAjax/', data).then( function (response) { if (response.data.status == 'success') { RegistryService.getItem("successModal").show(); setTimeout(()=>{ location.replace("/admin/index") }, 2000); } else if (response.data.status == 'error'){ RegistryService.getItem("errorModal").show(); } } ); } else { // 取消时无返回值,触发报错 } };
报错原因
代码里的错误提示存在表述问题,实际校验逻辑根本不是要求返回闭包,而是强制要求removeAction()的返回值必须带有then方法,也就是必须返回一个Promise(Thenable对象)。当用户点击取消时,else分支没有返回任何值(或者手动return false),返回值不存在then属性,自然就触发了抛出错误的逻辑。
修复方法
在用户点击取消的else分支,直接返回一个立即resolve的Promise即可,既满足校验规则,也能正常走到后续重置$scope.deleting状态的逻辑,不会出现按钮加载状态卡住的问题。
修改后的remove函数代码如下:
$scope.remove = function () { if (confirm("Confirm Delete?")){ var data = {}; data.id = EventService.event.id; // 原有删除请求逻辑保持不变 return $http.post('/admin/deleteAjax/', data).then( function (response) { if (response.data.status == 'success') { RegistryService.getItem("successModal").show(); setTimeout(()=>{ location.replace("/admin/index") }, 2000); } else if (response.data.status == 'error'){ RegistryService.getItem("errorModal").show(); } } ); } else { // 返回立即完成的Promise,通过校验同时重置加载状态 return $q.resolve(); } };
注意事项
- 使用该方案需要在当前控制器中注入
$q依赖,否则会抛出$q is not defined错误 - 如果不想额外注入
$q,也可以返回一个带then方法的立即完成对象,但$q.resolve()是最符合AngularJS规范、最轻量的实现方式 - 现有代码中用原生
setTimeout做延迟跳转,建议换成AngularJS内置的$timeout服务,避免离开视图前出现数据更新不触发脏检查的问题,该优化和本次报错无关
内容的提问来源于stack exchange,提问作者Dula
相关产品推荐
相关产品推荐

