Angular 1承诺服务

时间:2016-10-19 16:02:14

标签: javascript angularjs angularjs-service angular-promise

我一直在疯狂尝试在Angular 1.3中获得一些可能甚至不可能的东西......但它似乎应该是这样。基本上,我想编写一个只返回计算值而不是promise的服务。

我有一个服务,它发出$ http.get请求并返回一个promise。我想从另一个服务中调用它,获取数据,操作它并返回一个值。一旦我打电话给我,我就不想处理。我的理由是我想拥有一个可以调用的可共享函数并获得一个实际值,这样我就可以将它用作ng-show之类的条件。就像我说的那样,我会在控制器中编写这个函数,并使用.then为promise中的数据分配一个变量,但是我不想在我需要的每一个控制器中都写这个。

示例:

app.factory('searchService', ['$http', function($http) {
  return {
    performSearch: function(searchString) {
      return $http.get('http://asdf.com/search/' + searchString);
    },
    getItemCount: function(itemName) {
      var _this = this;
      this.count = 0;

      this.performSearch(itemName).then(
        function successCallback(resp) {
          _this.count = resp.data.items.length;
        },
        function errorCallback() {
          // This section doesn't matter right now
        };

       return this.count;
    }
  };
}]);

所以我想能够从控制器调用它并获得“5”或其他东西。或者甚至更好,从ng-show中调用它,例如“ng-show =”blahCtrl.getItemCount('item_search_string')== 0“。再次,我有多个控制器,我可能需要这个,所以我宁愿不重复遍布整个地方只是为了提取我需要的数字。

这对我来说不起作用......我的返回值始终是我最初设置this.count的原因。我已经在一些地方插入了一个console.log,并且已经看到(似乎)在回调函数可以设置其值之前返回this.count。无论我做什么,我都无法从这项服务中返回一个值,这让我发疯了!更让我困惑的是,如果我要从控制器内部执行此代码:

var _this = this;
searchService.performSearch('asdf').then(
  function(data) { _this.searchResults.data; }
);

它工作正常,我在searchResults变量内部获取我的promise数据没问题。由于某种原因,它在服务内部不起作用。

希望这是有道理的,我可能有点絮絮叨叨或不清楚。任何帮助都将非常感谢...我花了大量时间研究这个并尽可能地使用试验和错误。

谢谢!

2 个答案:

答案 0 :(得分:1)

我看到的一个解决方案。

将此一次放入控制器

app.controller('ctrl', function ($scope, searchService) {
   $scope.searchService = searchService;
   searchService.getItemCount();
});

并进入所有视图

{{ searchService.count }}

我认为,对每个ng-ifng-show等提出请求是不好的。

答案 1 :(得分:0)

您将需要使用$ q(https://docs.angularjs.org/api/ng/service/ $ q)。您的功能在履行承诺之前返回。你的getItemCount应如下所示:

app.factory('searchService', ['$http', '$q', function($http, $q) {
  return {
    performSearch: function(searchString) {
      return $http.get('http://asdf.com/search/' + searchString);
    },
    getItemCount: function(itemName) {
      var deferred = $q.defer();

      this.performSearch(itemName).then(
        function successCallback(resp) {
          deferred.resolve(resp.data.items.length);
        },
        function errorCallback(err) {
          deferred.reject(err);
        };

       return deferred.promise;
    }
  };
}]);