2015-07-13 70 views
1

我使用下面的代码为了简化后端请求,但我没有看到如何调用成功方法或错误方法。

如何达到在代码中注释的预期行为?

 
app.factory('REST', function ($http, $q, sweetAlert) { 

    return { 
     load: function (module, action, data) { 
      var deferred = $q.defer(); 
      var promise = deferred.promise;   
      $http 
      .post('/api/'+module+'.php?action='+action, data) 
      .success(function (data) { 

       if(data.error) 
       { 
        sweetAlert.swal({ 
         title: "Error", 
         text: data.error, 
         type: "warning" 
        }); 
       //HERE I WANT TO CALL .error(details) 
       } 
       else 
        deferred.resolve(data.result); 

         }).error(function() { 
       //HERE I WANT TO CALL .error(details) 
      }); 

      promise.success = function(fn) { 
       promise.then(fn); 
       return promise; 
      } 

      return promise; 
     } 
    }; 
}); 

这是使用上面的代码的代码:

$scope.login = function() { 
    $scope.loading = true; 
    var payload = {'credentials': $scope.logindata}; 
    REST.load('access', 'login', payload).success(function(data) { 
     if(data.redirect) 
      $state.go(data.redirect); 
     $scope.loading = false; 
    }).error(function(data) { //THIS SHOULD BE CALLED 
     $scope.loading = false; 
    }); 
} 
+0

经常承诺没有任何成功()/错误()函数。他们有一个then()和catch()函数。这些是你的客户端代码应该调用的。阅读http://blog.ninja-squad.com/2015/05/28/angularjs-promises/ –

+0

你的意思是说你想调用'.reject()',而不是'.error()'? – Bergi

回答

3

首先,我强烈劝阻你不要担心对您要退回的承诺给予.success。这不符合Promises/A标准,与.then(由$http实施)的细微差别导致了很多混淆。只是回报一个纯粹的承诺。

除此之外,几件事情需要注意:

1)你不需要另一个$q.deferdeferred.resolve() - 只是链的$httpreturn产生的诺言当初的诺言。 (见deferred anti-pattern

2)拒绝承诺 - 也就是造成.catch(不.error - 上面看到的细微差别)射击 - 你应该返回$q.reject()

以上全部产生以下:

app.factory('REST', function($http, $q, sweetAlert){ 
    return { 
    load: function(module, action, data) { 
     // this "return" returns the promise of $http.then 
     return $http.post('/api/' + module + '.php?action=' + action, data) 
     .then(function(response) { 
      var data = response.data; // .then gets a response, unlike $http.success 

      if (data.error) { 
      sweetAlert.swal({ 
       title: "Error", 
       text: data.error, 
       type: "warning" 
      }); 

      //HERE I WANT TO CALL .error(details) 

      return $q.reject(data.error); 
      } 

      return data.result; // what you would have "resolved" 
     }); 
    } 
    }; 
}) 

然后,正如我上面所说,使用.then/.catch,你会与承诺:

$scope.login = function() { 
    $scope.loading = true; 
    var payload = {'credentials': $scope.logindata}; 
    REST.load('access', 'login', payload) 
     .then(function(data) { 
      if(data.redirect) 
      $state.go(data.redirect); 
      $scope.loading = false; 
     }) 
     .catch(function(error) { 
      $scope.loading = false; 
     }); 
} 
1

更新年代码如下

app.factory('REST', function ($http, $q, sweetAlert) { 
    return { 
     load: function (module, action, data) { 
       var deferred = $q.defer();     
        $http.post('/api/'+module+'.php?action='+action, data) 
          .success(function (data) { 
           if(data.error) 
           { 
            sweetAlert.swal({ 
             title: "Error", 
             text: data.error, 
             type: "warning" 
            });  
           //HERE I WANT TO CALL .error(details)         
           deferred.reject(data.error); 
           } 
           else{ 
           deferred.resolve(data.result); 
           } 

         }) 
         .error(function (error) { 
           //HERE I WANT TO CALL .error(details) 
           deferred.reject(error); 
          }); 

       return defferred.promise; 
      } 
    }; 
}); 

为年控制器

$scope.login = function() { 
    $scope.loading = true; 
    var payload = {'credentials': $scope.logindata}; 
    REST.load('access', 'login', payload).then(
     function(data) { 
     if(data.redirect) 
      $state.go(data.redirect); 
      $scope.loading = false; 
     }, 
     function(error) { 
      $scope.loading = false; 
     }); 
    } 
+0

避免[deferred antipattern](http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

感谢您提请注意。 – nitin