繁体   English   中英

如何使控制器在angularjs中等待工厂响应?

[英]How to make the controller wait for factory response in angularjs?

我试图从工厂到控制器的响应。 但是,当我从控制器调用工厂函数时,则控制器不等待其响应。 并给出“未定义”。

这是我的controller.js

app.controller('customerCommentsController',function($scope,$http,$stateParams,$sce,$timeout,Comments){     

var commentsdata = '';

Comments.init(1,5);

$scope.total_comments = Comments.total();
console.log($scope.total_comments); //undefined 

$scope.positive_comments = Comments.positive();
console.log($scope.positive_comments);  //undefined 

$scope.commentsdata = Comments.getcomments(1,30);       
console.log($scope.commentsdata);   //undefined     
});

在这里,我正在调用init()方法,该方法从ajax获取响应,这需要花费一些时间来执行,但在此方法完成之前,另外2条语句(total()和positive()方法)在init方法下执行。 由于初始化方法未完成,因此无法初始化。 那就是为什么我变得不确定。 当我调用不等待其响应的getcomments方法时,也会出现相同的问题。

这是我的工厂

app.factory("Comments",function($http,$timeout,$q){

var commentshtml = [];
var commentshtml1 = [];

return {
    init :  function(start,end) {  
    var request = $http({   
            method:"post",
            url:"/comments.php",
            data: {start:start,end:end},                
            headers: {'Content-Type' : 'application/x-www-form-urlencoded'}                     
        });     

    request.success(function(data){                 
            commentshtml = data;            
        });             
    },      
    total : function() {

                return commentshtml.total_comment;                    
    },
    positive : function(){

            return commentshtml.per_positive_comment;               
    },
    getcomments : function(start,end) { 

        var promise  = $http({  
            method:"post",
            url:"/comments.php",
            data: {start:start,end:end},                
            headers: {'Content-Type' : 'application/x-www-form-urlencoded'}                     
        });

        promise.success(function(data){                 
            commentshtml1 = data.comments;
            console.log(commentshtml1); //giving the object             
            return commentshtml1;   
        }); 

    }
};

最好使用$ q模块与angular中的异步函数一起使用。 阅读此文档:

$ q文档

这样做:

在工厂

   return {
    init :  function(start,end) {  
     return $http({     //return the promise 
            method:"post",
            url:"/comments.php",
            data: {start:start,end:end},                
            headers: {'Content-Type' : 'application/x-www-form-urlencoded'}                     
        });     
    }
  getcomments : function(start,end) { 
             return $http({   //return the promise
            method:"post",
            url:"/comments.php",
            data: {start:start,end:end},                
            headers: {'Content-Type' : 'application/x-www-form-urlencoded'}                     
        });

}

在控制器中

Comments.init(1,5).then(function(){
 $scope.total_comments = Comments.total();
console.log($scope.total_comments);  

  $scope.positive_comments = Comments.positive();
console.log($scope.positive_comments);
 });
Comments.getcomments(1,30).then(function(data){
  $scope.commentsdata =data.comments;

})

或者是在ng-route或ui-router中使用resolve属性的最佳方法

您正在执行异步请求,问题是您在定义数据之前先检索数据。

一个好的做法是使用诺言 你脑水肿知道,$ http服务回报承诺,并有一定的回调方法,如.success().then()的例子。

为了保证,角度为我们提供了一个很好的工具: $ q.defer()

$ q.defer()是来自延迟API承诺管理器

$q.defer()得到2种方法:

  • resolve(value) :通过赋予她最终的价值来解决我们相关的承诺

  • reject(reason) :解决承诺错误。

因此,您可以执行以下操作:

调节器

(function(){

function Controller($scope, Comments) {

  //Retrieve our init promise
  var promise_init = Comments.init();

  //Retrieve our total promise
  var promise_total = Comments.total();

  promise_init.then(function(){
    //Return promise for chaining
    return promise_total;
  }).then(function(total){
    //Retrieve total of comments
    $scope.total = total;
  }).catch(function(err){
    //Catch error of total comments
    $scope.total = err;
  });

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

服务

(function(){

  function Service($q){

    var commentshtml = [];

    function init(){
      //Create defer object
      var defer = $q.defer();
      commentshtml = ['a', 'b', 'c'];
      //Simulate latency
      setTimeout(function(){
        //Resolve our promise
        defer.resolve();
      }, 2000);

      //Return a promise
      return defer.promise;
    }

    function total(){
      var defer = $q.defer();
      commentshtml.length < 3
      ? defer.reject('error length')
      : defer.resolve(commentshtml.length);
      return defer.promise;
    }


    return {
      init: init,
      total: total
    };

  }

  angular
    .module('app')
    .factory('Comments', Service);

})();

HTML

  <body ng-app='app' ng-controller='ctrl'>

    <h2>Total : {{total}}</h2>

  </body>

您可以看到工作柱塞

then函数中编写所有$scope变量。

所以你的Controller.js

app.controller('customerCommentsController',function($scope,$http,$stateParams,$sce,$timeout,Comments){     

    var commentsdata = '';

    Comments.init(1,5).then(function(){

         $scope.total_comments = Comments.total();
         console.log($scope.total_comments); //undefined 

         $scope.positive_comments = Comments.positive();
         console.log($scope.positive_comments);  //undefined 

         $scope.commentsdata = Comments.getcomments(1,30);       
         console.log($scope.commentsdata);   //undefined     
    }
});

您必须返回$http请求。

因此,您的init函数如下所示:

init : function(start,end) {  
return $http({   
        method:"post",
        url:"/comments.php",
        data: {start:start,end:end},                
        headers: {'Content-Type' : 'application/x-www-form-urlencoded'}                     
    }).success(function(data){
          return commentshtml = data;
    });
}

还有你的工厂:

app.factory("Comments",function($http,$timeout,$q){

var commentshtml = [];
var commentshtml1 = [];

return {
init :  function(start,end) {  
return $http({   
        method:"post",
        url:"/comments.php",
        data: {start:start,end:end},                
        headers: {'Content-Type' : 'application/x-www-form-urlencoded'}                     
    }).success(function(data){
          return commentshtml = data;
    });
},      
total : function() {

            return commentshtml.total_comment;                    
},
positive : function(){

        return commentshtml.per_positive_comment;               
},
getcomments : function(start,end) { 

    var promise  = $http({  
        method:"post",
        url:"/comments.php",
        data: {start:start,end:end},                
        headers: {'Content-Type' : 'application/x-www-form-urlencoded'}                     
    });

    promise.success(function(data){                 
        commentshtml1 = data.comments;
        console.log(commentshtml1); //giving the object             
        return commentshtml1;   
    }); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM