1

私の問題は、http 要求の最終的なコールバックでアクセスする必要があるデータをどこに保存するかわからないことです。jQueryでは、次のことを行うだけです

var token = $.get('/some-url', {}, someCallback);
token.oSomeObject = {data: 'some data'};

function someCallback( data, status, token ){
     token.oSomeObject.data // 'some data'
}

トークンを使用して、リクエスト固有のデータを保存します。

Angular でこれを実現する唯一の方法は、実際の構成にデータを保存することです。

var config = {
    url: '/some-url',
    method: 'GET',
    oSomeObject: { data: 'some data' }
};
$http(config).success(someCallback);

function someCallback( data, status, headers, config ){
     config.oSomeObject.data // 'some data'
}

1 つには、これにより省略形の呼び出し ($http.get、$http.post) を使用できなくなります。また、特定のサービス モジュールで呼び出しをラップするときに、はるかに目立たない方法であることがわかります。

これを行う他の方法はありますか?

明確にするために更新

promise API を適切に使用する方法を理解していないという簡単なことを見逃しているだけかもしれませんが、同じページにいることを確認するために、この問題についてもう少し詳しく説明します。

2 つのファイルがあります: 1) Controller.js 2) AjaxServices.js (すべての ajax 呼び出しは、サービスのメソッドとしてここで定義されます)。

AjaxServices.js は次のようになります。

app.service('AjaxService', function( $http ){
     var self = this;

     this.createUser = function( oUser, fSuccessCallback ){
          return $http.put('/api/user', {oUser: oUser})
                       .success(fSuccessCallback);
     }
}

Controller.js は次のようになります。

app.controller('MyController', function( $scope, AjaxServices ){
     $scope.saveUser = function( oUser ){
          var oPromise = AjaxServices.createUser( oUser, $scope.onUserSaved );

          oPromise.oUser = oUser // this is how I solve it in jQuery.ajax. The oPromise
                                 // is then sent as the token object in the onUserSaved
                                 // callback
     }
     $scope.onUserSaved = function( oStatus, status, headers, config ){
          oStatus.id // here is the id of the newly created user 
                     // which I want to now hook on to the oUser local object

     }
}

promise API を使用して同じことをどのように達成しますか?

4

1 に答える 1

2

更新 2。更新されたコードに関する注意事項: コールバックをサービスに渡す必要はありません。これは事実上、約束の目的を殺します。サービスをそのデータの消費者に結合することなく、その仕事に任せます。

app.service('AjaxService', function( $http ){
    var self = this;

    this.createUser = function( oUser ){
      return $http.put('/api/user', {oUser: oUser});
    }
}

これで、サービスはコールバックを気にしなくなりました。つまり、同じサービスの $http 呼び出しに複数のコールバックをアタッチできます。では、サービス データ コンシューマーに移りましょう。この場合はコントローラーです。

app.controller('MyController', function( $scope, AjaxServices ){
  $scope.saveUser = function( oUser ){
    var oOriginalPromise = AjaxServices.createUser( oUser );
    //lets modify the orginal promise to include our oUser
    var oModifiedPromise = oOriginalPromise.then(function(response) {
      response.oUser = oUser; 
      return response;
    });
    //in the code above we've chained original promise with .then,
    //modified response object and returned it for next promise to receive
    //at the same time, .then created a new promise

    //finally, after modifying our response, we can pass it to the desired callback. 
    //note, that .success and .error are $http specific promise methods, 
    //in all other cases use .then(fnSuccess, fnError)
    oModifiedPromise.then($scope.onUserSaved); 
  }
  $scope.onUserSaved = function(responseWithUser) {
    responseWithUser.oUser;
  }
}

もちろん、oUser はコントローラーのスコープに保存でき、そこから $scope.onUserSaved で直接アクセスできるため、これはまだ少し厄介です。

更新します。私の答えを明らかにします。Promise は、任意のスコープで、どこでもチェーンできます。サービスによってトークンが挿入される別の例を次に示します。

myModule.factory('Service', function($http) {
   return new function() {
      this.getData = function() {
        return $http.get(url).then(function(response) {
          response.token = myToken;
          return response;
        }
      }
   }
});

$http サービスを拡張またはラップし、サービスが認識しなくても応答にトークンを挿入することもできます。

すべてのリクエストでこれを行う場合、おそらく $httpInterceptor の方が適切でしょう。http 呼び出しのインターセプトについて詳しくは、こちらをご覧ください。

元の答え

promise を提供するので$http、応答としてトークンを挿入する別の promise にチェーンできます。

myModule.factory('Service', function($http) {
   return new function() {
      this.getData = function() {
        return $http.get(url);
      }
   }
});

//in controller or other service:
var myToken;
var tokenizedPromise = Service.getData().then(function(response) {
  response.token = myToken;
  return response;
});

プロミスの最終消費者もトークンにアクセスできます

于 2013-08-20T13:40:04.527 に答える