2013-11-02 2 views
17

Ich versuche, etwas sehr ähnlich zu dem $ http-Dienst zu tun. Von meinem Verständnis $ http gibt ein Versprechen-Objekt zurück. eine Verheißung in angularJS mit named Erfolg/Fehler Callbacks zu deklarieren

Wenn es die Syntax ist:

$http(...).success(function(data)) { 
    //success callback 
}).error(function(data)) { 
    //error callback 
}) 

ich nur das Gleiche tun möchten, aber betrachten meine API GetUserProfile ist, so möchte ich die Syntax haben:

GetUserProfile(...).success(function(data) { 
    // success callback 
}).error(function(data)) { 
    // error callback 
}) 

wie kann Ich erreiche das mit einem Versprechen?

+0

Sie einen Blick darauf werfen konnte, wie Angularjs Geräte [dies in '$ http'] (https:. // Github .com/angular/angular.js/blob/v1.2.0-rc.3/src/ng/http.js # L701). – TheHippo

Antwort

27

Die nette Sache mit Open-Source ist, dass Sie die Quelle lesen kann. Hier ist, wie der $ http-Dienst es macht:

+0

Schön :) Danke! –

+3

Ich frage mich, warum das native $ q in eckig dies nicht hat. –

+1

Response Interceptors sind [veraltet] (https://code.angularjs.org/1.2.20/docs/api/ng/service/$http#response-interceptors-deprecated-) in 1.3+, aber das gleiche Konzept gilt immer noch . Verwenden Sie etwas wie: 'promise.success = function (fn) {return promise.then (fn); }); provey.error = function (fn) {return promise.then (null, fn); }); ' – nwayve

9

Sie müssen die $ q Service nutzen und erstellen und senden Sie Ihre eigenen Versprechen in GetUserProfile:

function GetUserProfile() { 
    var deferred = $q.defer(); 
    var promise = deferred.promise; 

    // success condition 
    if (!true) { 
     deferred.resolve('data'); 
    // error condition 
    } else { 
     deferred.reject('error'); 
    } 

    promise.success = function(fn) { 
     promise.then(fn); 
     return promise; 
    } 

    promise.error = function(fn) { 
     promise.then(null, fn); 
     return promise; 
    } 

    return promise; 
} 

GetUserProfile() 
    .success(function(data) { 
     console.log(data); 
    }) 
    .error(function(error) { 
     console.error(error); 
    }); 
+0

Ich bin mir dessen bewusst .. aber immer noch die Erfolg/Fehler-Syntax in $ http wird hier nicht gelten. oder vielleicht wird es? Ist die Erfolgs-/Fehlersyntax standardmäßig verwendet, wenn ein Versprechen zurückgegeben wurde? –

+1

Ich habe die Frage missverstanden. Nein, das Verspreungsobjekt hat standardmäßig keine Erfolgs- und Fehlermethoden. – katranci

+0

Ich habe meine Antwort bearbeitet und die Erfolgs-/Fehler-Methoden zum Versprechungsobjekt hinzugefügt. – katranci

9

Sie brauchen nicht ändern Quellcode. Angular bieten eine Möglichkeit, jeden Service in eckigen ändern $ q.

$ provide.decorer ist perfekt für Ihre Anforderung Hier ist mein Code.

legte es auf app.module ('...') Config

$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; 
}); 
+0

Die meisten Antworten, wie dies zu tun ist, bricht die Fähigkeit, Versprechen zusammen zu verketten, während Ihre Lösung diese Fähigkeit bewahrt, ziehe ich Ihre Antwort vor. –

Verwandte Themen