2013-11-02 3 views
17

私は$ httpサービスとよく似た何かをしようとしています。私の理解から$ httpは約束オブジェクトを返します。名前付き成功/エラーコールバックでangularJSの約束を宣言する

構文は、それを使用して:

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

私はちょうど同じことをやりたいが、私のAPIを検討することGetUserProfileあるので、私は構文を持つことを望む:

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

どのようにすることができます私は約束を使ってそれを達成しますか?

+0

設定:// githubのを.com/angular/angular.js/blob/v1.2.0-rc.3/src/ng/http.js#L701)。 – TheHippo

答えて

27

オープンソースとの良いところは、あなたがソースを読むことができるということです。 $ httpサービスでは以下のようになります。

promise.success = function(fn) { 
    promise.then(function(response) { 
     fn(response.data, response.status, response.headers, config); 
    }); 
    return promise; 
    }; 

    promise.error = function(fn) { 
    promise.then(null, function(response) { 
     fn(response.data, response.status, response.headers, config); 
    }); 
    return promise; 
    }; 
+0

ニース:)ありがとう! –

+3

私は、角度のネイティブ$ qがこれを持っていないのだろうかと思います。 –

+1

レスポンスインターセプタは、1.3+では[非推奨](https://code.angularjs.org/1.2.20/docs/api/ng/service/$http#response-interceptors-deprecated-)ですが、同じ概念がそのまま適用されます。 'promise.success = function(fn){return promise.then(fn);}のようなものを使用します。 }); promise.error = function(fn){return promise.then(null、fn); }); ' – nwayve

9

あなたは$ qをサービスを使用して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

私はそれを認識していますが、$ httpで使用されている成功/エラーの構文はここでは適用されません。それともそれは?約束が返されたときに成功/エラー構文がデフォルトで使用されますか? –

+1

私はその質問を誤解しました。いいえ、promiseオブジェクトにはデフォルトで成功とエラーのメソッドがありません。 – katranci

+0

私は自分の答えを編集し、成功/エラーメソッドをpromiseオブジェクトに追加しました。 – katranci

9

変更ソースコードは必要ありません。 角度角度incl $ qのサービスを変更する方法を提供します。

$ provide.decoratorはあなたの要件に最適です ここに私のコードです。

は( '...')app.moduleでそれを置く方法(HTTPS [ `$ http`でこの]実装angular.jsであなたが見てみることができ

$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

これを行う方法のほとんどの応答は、約束を連鎖させる能力を破りますが、あなたの解決策はその能力を保持します。 –

関連する問題