angularjs extend override promise angularjs-service

¿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.