如何将承诺传递给AngularJS中的控制器

时间:2015-08-21 14:43:25

标签: javascript angularjs promise angular-promise

我无法理解承诺。我有一个函数$scope.startJob,在调用时,它会调用areThereAvailableSegments中的SegmentsService。我的想法是areThereAvailableSegments应返回true或false,以便我可以在控制器中处理此行为,但不知道如何执行此操作。

areThereAvailableSegments调用getSegments(),它从数据库中请求文本段。 getSegments会返回一个承诺,我试图在.then中使用areThereAvailableSegments来处理此承诺,但不知道如何传递给控制器​​。

这是我的Segments工厂,返回$resource对象,segmentsfactory.js

angular.module('appApp')
  .factory('SegmentsFactory', function ($resource) {
    return $resource('http://localhost:3000/api/v1/segments/:id');
  });

这是我的细分服务segmentsservice.js

angular.module('appApp')
  .service('SegmentsService', function (SegmentsFactory) {

    // gets segments from mongo
    this.getSegments = function(jobId) {
      return SegmentsFactory.query({ job_id: jobId }).$promise;
    };

    // should return true/false if there are available segments
    this.areThereAvailableSegments = function(jobId) {
      var dump = [];

      // queries for all segments
      this.getSegments(jobId)
      .then(function(segments) {
        // dumps segments status in a temp array
        for (var i = 0; i < segments.length; i++) {
          dump.push(segments[i].status);
        }
        // returns true if there is an 'available' in the temp array
        if (dump.indexOf('available') >= 0) {
          return true;
        } else {
          return false;
        }
      });
    };

  });

这是我的控制器main.js

$scope.startJob = function() {

  if (SegmentsService.areThereAvailableSegments(jobId)) {
    console.log('there are available segments, then trigger texteditor');
  } else {
    console.log('no segments to translate');
  }
};

执行时,控制台显示&#34;没有要翻译的段&#34;,因为SegmentsService没有返回true或false。

如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

没有理由同时拥有服务和工厂。删除工厂并将该代码移动到服务中。至于你的问题,你将不得不使用$ q模块来返回一个promise。 https://docs.angularjs.org/api/ng/service/ $ Q

this.areThereAvailableSegments = function(jobId) {
  var dump = [];
  var deferred = $q.deferred;

  // queries for all segments
  this.getSegments(jobId)
  .then(function(segments) {
    // dumps segments status in a temp array
    for (var i = 0; i < segments.length; i++) {
      dump.push(segments[i].status);
    }
    // returns true if there is an 'available' in the temp array
    if (dump.indexOf('available') >= 0) {
      deferred.resolve(true);
    } else {
      deferred.resolve(false);
    }
  });

  return deferred.promise;
};

然后你必须处理控制器中的承诺。

答案 1 :(得分:2)

函数areThereAvailibleSegments也应该返回一个promise。 然后在你的控制器中你有一个案例,并在那里有你的if-else。

this.areThereAvailableSegments = function(jobId) {
      var dump = [];

      // queries for all segments
      return this.getSegments(jobId) //Return here
      .then(function(segments) {
        // dumps segments status in a temp array
        for (var i = 0; i < segments.length; i++) {
          dump.push(segments[i].status);
        }
        // returns true if there is an 'available' in the temp array
        if (dump.indexOf('available') >= 0) {
          return true; 
        } else {
          return false;
        }
      });
    };

因为你的success函数返回true或false,来自areThereAvailibleSegments的函数的函数将具有该布尔值。

然后在你的控制器中:

SegmentsService.areThereAvailableSegments(jobId).then(function(available){
  if (available) {
      console.log('there are available segments, then trigger texteditor');
    } else {
      console.log('no segments to translate');
    }
});

答案 2 :(得分:0)

我会这样设置......在你的工厂完成承诺然后调用控制器中的数据。

在您的服务js:

    .factory('SegmentsFactory', function ($resource) {

             var APIRequest = {};

            APIRequest.getSegments = function(id){
                    segmentsAPI = $resource('http://localhost:3000/api/v1/segments/'+id'', ;
                    return segmentAPI.get().$promise.then(function(segments){
                        console.log(segments);
                        return segments;
                    });
                };

        return APIRequest;
}]);

然后在你的控制器中:

var dump = [];
        $scope.startJob = function() {

          if (SegmentsService.areThereAvailableSegments) {
             APIRequest.getSegments($scope.id).then(function(data){
                        if (data.error){
                            //error stuff here
                        } else {
                            if (data.segments.length > 0){
                                for(var i=0; i < segments.length; i++){
                                console.log(segments);
                                dump.push(segments[i].status);
        }

    };