Angular JS:存储承诺数据

时间:2013-08-20 12:01:32

标签: javascript angularjs

我的问题是我不知道在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'
}

对于一个这会阻止你使用短手调用($ 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实现相同的目标?

1 个答案:

答案 0 :(得分: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中直接从那里访问。

<强>更新即可。我会澄清我的答案。您可以在任何范围内随处链接承诺。这是服务注入令牌的另一个例子:

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电话here

原始回答

由于$http为您提供了承诺,您可以将其链接到另一个承诺,该承诺会在响应中注入令牌:

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;
});

承诺的最终消费者也可以访问令牌