當我嘗試從帶有 Angular 的工廠函式回傳一個 $http.post() 物件時,它拋出了這個錯誤:

下面是我的代碼:
AngularUtils.js
Fenrir.factory('AngularUtils', function ($http, $log, $window) {
var AngularUtils = {
save: function(url, obj, errors, not_show_error_toast) {
not_show_error_toast = typeof not_show_error_toast !== 'undefined' ? not_show_error_toast : false;
loaderShow();
if (angular.isDefined(obj.id)) {
return $http.put(url obj.id '/', obj).
then(function onSuccess(response) {
loaderHide();
angular.extend(obj, response);
errors = {};
}), function onError(response) {
loaderHide();
handleErrors(response, status, errors, not_show_error_toast);
};
} else {
return this.create(url, obj, errors, not_show_error_toast);
}
},
create: function(url, obj, errors, not_show_error_toast) {
not_show_error_toast = typeof not_show_error_toast !== 'undefined' ? not_show_error_toast : false;
return $http.post(url, obj).
then(function onSuccess(response) {
loaderHide();
angular.extend(obj, response);
errors = {};
}), function onError(response) {
loaderHide();
handleErrors(response, status, errors, not_show_error_toast);
};
},
}
return AngularUtils
})
管理.js
var Fenrir = angular.module('Fenrir', []);
Fenrir.controller('AdminController', function ($scope, $http, AngularUtils) {
$scope.createScreen = function () {
AngularUtils.save('/admin/saveScreen', $scope.record, '', '').then(function (hubs) {
$scope.hubs = hubs;
console.log('In ctrl ' $scope.hubs);
});
}
})
如何正確回傳 $http.post() 物件?
uj5u.com熱心網友回復:
仔細查看錯誤資訊:
TypeError: AngularUtils.save(...).then is not a function
這就是說沒有then()從 回傳的命名函式AngularUtils.save(...)。這表明該save()函式確實執行了,但它沒有按預期回傳承諾。
所以你的工廠方法確實執行了,但是因為你沒有回傳一個 promise,我們只能推測執行最終導致了哪條路徑。
更新:原始腳本中的語法錯誤
在嘗試為您證明我的解決方案時,我發現您的$put().then()回應處理程式有一個語法問題,在錯誤的地方有一個括號,該onError函式應該是該then函式的第二個引數,而不是在它之后。您的代碼應如下所示:
return $http.put(url obj.id '/', obj).
then(function onSuccess(response) {
loaderHide();
angular.extend(obj, response);
errors = {};
}, function onError(response) {
loaderHide();
handleErrors(response, status, errors, not_show_error_toast);
});
微妙但重要的是,如果您沒有嚴格編譯,那么工廠函式根本沒有正確編譯,這可能會導致您的錯誤。
在一個或一些路徑將回傳異步承諾延遲(期貨)的工廠方法中,默認模式雖然冗長,但回傳圍繞整個方法執行的單個延遲,然后對于每個回應路徑,您可以選擇解決或通過從函式回傳的原始承諾拒絕回應。
有不同的庫和技術可以做到這一點,請參閱Rick Strahl 的帶有 $http 服務的AngularJs 和 Promises,了解常見實作的演練。
save: function(url, obj, errors, not_show_error_toast) {
var defer = $.Deferred();
not_show_error_toast = typeof not_show_error_toast !== 'undefined' ? not_show_error_toast : false;
if (angular.isDefined(obj.id)) {
loaderShow(); // NOTE: let create manage the loader start if it needs to
$http.put(url obj.id '/', obj).
then(function onSuccess(response) {
loaderHide();
// HACK: because .then is used instead of .success, you probably want the response.data, please review this
angular.extend(obj, response.data);
defer.resolve(obj);
}, function onError(response) {
loaderHide();
handleErrors(response, status, errors, not_show_error_toast);
defer.reject(response);
});
} else {
// If create is a deferral, it should be safe to return it directly
return this.create(url, obj, errors, not_show_error_toast);
}
return defer.promise();
},
Note: Only call a start or show utility or state operation in the same scope that also calls the reciprocal end/hide/stop/close. The code can work if you do not follow this rule but it gets harder to maintain as your project evolves, for that reason I've moved the
loaderShow();call into the branch that we know will always callloaderHide(). This functional scope can not make the assumption that thecreate()function will eventually callloaderHide()for us.This is a common, but bad habbit we all need to grow out of ;)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/312568.html
標籤:javascript angularjs 目的 错误处理 角度工厂
上一篇:如何將陣列合并為JSON陣列
下一篇:如果未選中復選框之一,則禁用按鈕
