AngularJS1:如何创建在应用程序加载时从API获取的常量映射

时间:2019-05-10 20:34:52

标签: angularjs api

我有一个angularJS 1应用程序,并在其中创建了一个工厂,该工厂调用API来获取一些常量,并使用这些常量创建映射。

app.factory('myFactory', '$http', function($http) {
  this.myMap = {};
  $http({
    method: 'GET',
    url: 'url',
    headers: {'Content-Type': '*/*'}
  }).then(function (response) {
    for (var i in response.data) {
      this.myMap[response.data[i].key] = response.data[i].value;
    }
  }).finally(function() {
    return {
      getMyValue: function(key) {
        return this.myMap[key];
      }
    };
  });
});

现在,我希望只在应用程序加载时创建和实例化该工厂一次,然后,我想从控制器中调用工厂的getMyValue()方法以从Map中获取值。

现在,使用上面的代码失败,并且给了我这个错误:

  

https://code.angularjs.org/1.7.8/docs/error/ng/areq?p0=fn&p1=not%20a%20function,%20got%20string

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

您的工厂没有退货。在服务中,您需要将功能和成员附加到this上,但是在工厂中,必须返回某些内容。

我看到您在.finally()块中有一个return语句,但这对您的工厂没有任何作用,因为该代码直到实例化工厂很长时间之后才在范围内。

我个人会放弃.finally()区块,因为它并没有真正给您带来任何额外的好处:

app.factory('myFactory', '$http', function($http) {
  var myMap = {};
  var apiPromise;

  // this will only run once as soon as the factory is instantiated
  // and will store the resolution of the call for future use
  apiPromise = $http({
        method: 'GET',
        url: 'url',
        headers: {'Content-Type': '*/*'}
     }).then(function (response) {
       for (var i in response.data) {
         myMap[response.data[i].key] = response.data[i].value;
       }
     });


  return {
    getMyValue: function(key) {
      // apiPromise prevents this function from returning until $http call is complete
      // but will not cause the $http call to run again
      return apiPromise.then(function() {
        return myMap[key];
      });
    }
  };

});

要使用此功能,您必须将返回值视为承诺而不是值:

MyFactory.getMyValue(key).then(function(myMap) {
  console.log(myMap);
});