¿Cómo puedo extender $ q promesa en Angularjs con un.success y.error
override promise (3)
Escribí este pequeño código en un servicio personalizado en AngularJS.
En mi servicio:
var deferred = $q.defer();
var promise = deferred.promise;
deferred.resolve(''success'');
deferred.reject(''error'');
/* Handle success and error */
promise.success = function(fn) {
promise.then(function(response) {
fn(response);
});
return promise;
};
promise.error = function(fn) {
promise.then(null, function(response) {
fn(response);
});
return promise;
};
En mi controlador:
promiseService.myPromise()
.success(function(data){
$scope.success= data;
})
.error(function(data){
$scope.error = data;
});
Juste Manejar el éxito y el error de la promesa (servicio $ q). Necesito este código en muchos otros servicios, así que extendería directamente el servicio $ q con un servicio personalizado.
Así que me gustaría algo como esto en mi servicio:
var deferred = myPromiseService.$qCustom.defer();
var promise = deferred.promise;
deferred.resolve(''success'');
deferred.reject(''error'');
return promise;
¿Alguna idea? Encontré una explicación para extender el filtro en Angularjs. Mi problema es encontrar la manera de extender toda la funcionalidad de $ q y agregar mi personalización.
Empiezo con algo así, es un trabajo manejar los $ q de la caja:
angular.module(''myApp'').service(''myPromiseService'', function($q){
$qCustom = $q;
});
Aquí hay una solución completa retomando donde @jessegavin lo dejó.
var myApp = angular.module("myApp", []);
myApp.config(function ($provide) {
$provide.decorator(''$q'', function ($delegate) {
var defer = $delegate.defer;
$delegate.defer = function () {
var deferred = defer();
deferred.promise.success = function (fn) {
deferred.promise.then(function(response) {
fn(response.data, response.status, response.headers);
});
return deferred.promise;
};
deferred.promise.error = function (fn) {
deferred.promise.then(null, function(response) {
fn(response.data, response.status, response.headers);
});
return deferred.promise;
};
return deferred;
};
return $delegate;
});
});
En mi humilde opinión, la decoración de @jessegavin de $ q no es perfecta, no debería devolver la promesa de origen en la función de éxito y error. Se perderá característica de aplanar la pirámide de devolución de llamada.
Y no puede dividir los datos de respuesta para la función de éxito y error $ httpPromise dosis.
por ejemplo
//can''t do this..
somePromise.success(function(){
return $http.get(...)//another primise
}).success(function(data){
//data from $http.get..
})
Aquí está mi versión, reconocerá la respuesta de http y devolverá la próxima promesa. Haga su propio $ q tiene el mismo comportamiento como $ httpPromise
$provide.decorator(''$q'', function($delegate) {
function httpResponseWrapper(fn) {
return function(res) {
if (res.hasOwnProperty(''data'') && res.hasOwnProperty(''status'') && res.hasOwnProperty(''headers'') && res.hasOwnProperty(''config'') && res.hasOwnProperty(''statusText'')) {
return fn(res.data, res.status, res.headers, res.config, res.statusText);
} else {
return fn(res);
}
};
};
function decorator(promise) {
promise.success = function(fn) {
return decorator(promise.then(httpResponseWrapper(fn)));
};
promise.error = function(fn) {
return decorator(promise.then(null, httpResponseWrapper(fn)));
};
return promise;
};
var defer = $delegate.defer;
$delegate.defer = function() {
var deferred = defer();
decorator(deferred.promise);
return deferred;
};
return $delegate;
});
Si desea cambiar el comportamiento predeterminado de algo que es inyectado por angular, puede usar el método decorator()
en el servicio $provide
.
var myApp = angular.module("myApp", []);
myApp.config(function ($provide) {
$provide.decorator("$q", function($delegate) {
// The $delegate argument here refers to the $q service.
$delegate.defer = function() {
alert("You just tried to call defer()!");
};
// Now, every time angular provides an instance of $q via
// injection, it will return your customized version of $q.
return $delegate;
});
});
Vea el ejemplo anterior en acción en http://plnkr.co/edit/RuZF2cGkVHwlu7NIhxEZ?p=preview
En cuanto a modificar $q
para agregar las funciones de éxito y error, no estoy seguro en este momento. Pero estoy bastante seguro de que aquí es donde querrías hacerlo.