使用AngularJS中的Promise链接两个不同的控制器

时间:2014-08-25 14:08:46

标签: javascript angularjs

我的REST服务provider名为MyRestServices

app.provider('MyRestServices', function() {
  this.baseUrl = null;
  this.setBaseUrl = function(_baseUrl) {
    this.baseUrl = _baseUrl;
  };

  this.$get = ['$http', function($http) {
    var _baseUrl = this.baseUrl;

    function getMyData() {
      return $http.get(_baseUrl + 'data1/?token=' + token + '&key=' + key);
    }

    function preGetTokenAndKey() {
      return $http.get(_baseUrl + 'keyAndToken/');
    }

    return {
      getMyData: getMyData,
      preGetTokenAndKey: preGetTokenAndKey
    };
  }];
});

我在调用第一个REST服务之前配置它。

app.config(function(MyRestServicesProvider) {
  MyRestServicesProvider.setBaseUrl('https://www.test.com/rest/');
});

然后我有一个HeadCtrl控制器,应该调用preGetTokenAndKey来获取keytoken,这是其他一些REST调用所需要的getMyData

app.controller('HeadCtrl', function (MyRestServices) {
  MyRestServices.preGetTokenAndKey().success(function(data) {
    var key = data.dataSection.key;
    var token = data.dataSection.token;
  });
});

我的问题是我想从其他控制器拨打getMyData,但我需要keytoken才能拨打此电话。 所以我需要等到preGetTokenAndKey成功,我必须向MyRestServices提供商提供这两个值。 我该如何解决这些问题?

2 个答案:

答案 0 :(得分:4)

听起来更好的解决方案是将它们链接到您的服务本身。您将在preGetTokenAndKey中设置自己的承诺,该承诺将通过$ http调用解析。对preGetTokenAndKey()的后续调用只会返回已解析的数据,而无需进行额外的$ http调用。

所以下面的内容应该让你开始:

app.provider('MyRestServices', function() {
  this.baseUrl = null;
  this.setBaseUrl = function(_baseUrl) {
      this.baseUrl = _baseUrl;
  };

  this.$get = ['$http', function($http) {
    var _baseUrl = this.baseUrl;
    var _tokenAndKey = {};

    function getMyData() {
      return preGetTokenAndKey().then(function (data) {
            return $http.get(_baseUrl + 'data1/?token=' + data.dataSection.token + '&key=' + data.dataSection.key);
      });
    }

    function preGetTokenAndKey() {
      if(!_tokenAndKey.set) {
           _tokenAndKey.deferred = $http.get(_baseUrl + 'keyAndToken/').then(function(data) {
                _tokenAndKey.set = true;
                return data;
           });
      }
      return _tokenAndKey.deferred.promise;
    }

    return {
      getMyData: getMyData,
      preGetTokenAndKey: preGetTokenAndKey
    };
  }];
});

答案 1 :(得分:1)

  

我的问题是我想从另一个控制器调用getMyData,

如果是这样,您可以使用$broadcast通知其他控制器已解决异步呼叫并且您有密钥/令牌

app.controller('HeadCtrl', function($rootScope, MyRestServices) {
    MyRestServices.preGetTokenAndKey().success(function(data) {
        var key = data.dataSection.key;
        var token = data.dataSection.token;

        $rootScope.$broadcast("getMyDataTrigger", {key: key,token: token}); 
    });
});

在其他控制器实现监听器中:

$rootScope.$on("getMyDataTrigger", function(event, data){

        if(data){
           MyRestServices.getMyData(data.key, data.token);
           // ...
        }

    });

只需覆盖getMyData

function getMyData(key, token) {
  return $http.get(_baseUrl + 'data1/?token=' + token + '&key=' + key);
}