3

我有一个名为“Server”的工厂,其中包含我与服务器交互的方法(get/put/post/delete..)。当我的控制器中有所有代码时,我设法成功登录并获取所有数据。现在我想分离这段代码并稍微重组它,我遇到了问题。我仍然可以登录,也可以获取数据——但数据只是打印出来的;我不确定如何访问控制器中的数据?我在网络上到处都看到了一些“.then”而不是“.success”,但我不知道具体如何。

这是我的工厂:(包含在 services.js 中)

app.factory('Server', ['$http', function($http) {
    return {
        // this works as it should, login works correctly
       login: function(email,pass) {
            return $http.get('mywebapiurl/server.php?email='+email+'&password='+pass').success(function(data) {
                console.log("\nLOGIN RESPONSE: "+JSON.stringify(data));
                if(data.Status !== "OK")
                   // login fail
                   console.log("Login FAIL...");
                else
                   // success   
                   console.log("Login OK...");
                });
        },

        // intentional blank data parameter below (server configured this way for testing purposes)
        getAllData: function() {
            return $http.get('mywebapiurl/server.php?data=').success(function(data) {
                console.log("\nDATA FROM SERVER: \n"+data); // here correct data in JSON string format are printed
            });
        },
    };

}]);

这是我的控制器:

app.controller("MainController", ['$scope', 'Server', function($scope, Server){ 

   Server.login();   // this logins correctly   

   $scope.data = Server.getAllData(); // here I want to get data returned by the server, now I get http object with all the methods etc etc.

  …. continues … 

如何获取在工厂中使用 $http 检索到的数据以在控制器中访问?我只有一个控制器。

感谢您的帮助,我相信一定有一种简单的方法可以做到这一点。还是我可能采取了错误的方法来解决这个问题?

编辑:例如,我还需要能够使用 ng-click 从视图中调用工厂函数。现在我可以这样做:

// this is a method in controller
$scope.updateContacts = function(){
    $http.get('mywebapiURL/server.php?mycontacts=').success(function(data) {
        $scope.contacts = data;
    }); 
};

并使用 ng-click="updateContacts()" 在视图中进行调用。查看 $scope.contacts 如何在上述函数中获取新数据。我应该如何使用 .then 方法执行此操作?(将返回的数据分配给变量)

我的问题直截了当地问:

假设我需要将部分控制器代码与其分开(这样它就不会变得一团糟),比如在所有 $scope 中都可用的一些函数。在 AngularJS 中实现这一目标的最佳方法是什么?也许不是我想的服务……

4

2 回答 2

3

诀窍是在您的服务中使用承诺来代理结果。

$http 服务返回一个promise,您可以使用 then 来解决这个问题,使用列表或成功和错误来分别处理这些条件。

此代码块显示处理调用结果:

var deferred = $q.defer();
$http.get(productsEndpoint).success(function(result) {
    deferred.resolve(result);
}).error(function(result) { deferred.reject(result); });
return deferred.promise;

该代码使用 Angular $q 服务来创建一个承诺。当 $http 调用被解析时,promise 用于将信息返回给您的控制器。控制器像这样处理它:

app.controller("myController", ["$scope", "myService", function($scope, myService) {
    $scope.data = { status: "Not Loaded." };
    myService.getData().then(function(data) { $scope.data = data; });
}]);

(如果要显式处理拒绝,可以将另一个函数传递给 then)。

这就结束了循环:一个使用 Promise 来返回数据的服务,以及一个调用该服务并将 Promise 链接到结果的控制器。我在这里有一个完整的在线小提琴:http: //jsfiddle.net/HhFwL/

您可以更改端点,现在它只是指向通用 OData 端点以获取一些产品数据。

更多关于 $http:http: //docs.angularjs.org/api/ng.%24http 更多关于 $q:http ://docs.angularjs.org/api/ng.%24q

于 2014-02-11T12:57:59.640 回答
0

$http.get 返回一个 HttpPromise 对象

 Server.getAllData().then(function(results){

   $scope.data = results;
 })
于 2014-02-11T12:13:37.953 回答