简体   繁体   English

AngularJS:使用工厂内的$ http接收数据,以便在控制器内部访问

[英]AngularJS: make data received with $http inside factory to be accessible inside controller

I have a factory called "Server" which contains my methods for interaction with the server (get/put/post/delete..). 我有一个名为“Server”的工厂,它包含我与服务器交互的方法(get / put / post / delete ..)。 I managed to login and get all data successfully when I had all my code in my controller. 当我在控制器中拥有所有代码时,我设法登录并成功获取所有数据。 Now that I want to separate this code and restructure it a little bit I ran into problems. 既然我想要分离这些代码并重新构建它,我遇到了问题。 I can still login and I also get data - but data is just printed; 我仍然可以登录,我也可以获取数据 - 但数据只是打印出来; I'm not sure how to access the data in controller? 我不确定如何访问控制器中的数据? I saw some ".then" instead of ".success" used here and there across the web, but I don't know how exactly. 我在网上看到了一些“.then”而不是“.success”,但我不知道究竟是怎么回事。

This is my factory: (included in services.js) 这是我的工厂:(包含在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
            });
        },
    };

}]);

This is my controller: 这是我的控制器:

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 … 

How do I get data that was retrieved with $http within a factory to be accessible in controller? 如何在工厂中获取使用$ http检索的数据,以便在控制器中访问? I only have one controller. 我只有一个控制器。

Thanks for any help, I'm sure there must be an easy way of doing this. 感谢您的帮助,我相信必须有一个简单的方法来做到这一点。 Or am I perhaps taking a wrong way working this out? 或者我可能采取错误的方式解决这个问题?

EDIT: I also need to be able to call factory functions from views with ng-click for instance. 编辑:我还需要能够使用ng-click从视图中调用工厂函数。 Now I can do this like this: 现在我可以这样做:

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

and make a call in a view with ng-click="updateContacts()". 并使用ng-click =“updateContacts()”在视图中进行调用。 See how $scope.contacts gets new data in the above function. 了解$ scope.contacts如何在上述函数中获取新数据。 How am I supposed to do this with .then method?(assigning returned data to variable) 我怎么用.then方法做到这一点?(将返回的数据分配给变量)

My question asked straight-forwardly: 我的问题直截了当地问:

Lets say I need parts of controller code separated from it (so it doesn't get all messy), like some functions that are available throughout all $scope. 假设我需要将部分控制器代码与它分开(因此它不会弄得一团糟),就像所有$ scope中可用的一些函数一样。 What is the best way to accomplish this in AngularJS? 在AngularJS中实现此目的的最佳方法是什么? Maybe it's not services as I thought … 也许这不是我认为的服务......

The trick is to use a promise in your service to proxy the results. 诀窍是在服务中使用promise来代理结果。

The $http service returns a promise that you can resolve using then with a list or success and error to handle those conditions respectively. $ http服务返回一个承诺,您可以使用列表或成功和错误分别处理这些条件。

This block of code shows handling the result of the call: 这段代码显示了处理调用的结果:

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

The code uses the Angular $q service to create a promise. 该代码使用Angular $ q服务来创建一个promise。 When the $http call is resolved then the promise is used to return information to your controller. 解析$ http调用后,将使用promise将信息返回给控制器。 The controller handles it like this: 控制器像这样处理它:

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

(Another function can be passed to then if you want to explicitly handle the rejection). (如果你想明确处理拒绝,可以传递另一个函数)。

That closes the loop: a service that uses a promise to return the data, and a controller that calls the service and chains the promise for the result. 这将关闭循环:一个使用promise返回数据的服务,以及一个调用服务并链接结果承诺的控制器。 I have a full fiddle online here: http://jsfiddle.net/HhFwL/ 我在网上有一个完整的小提琴: http//jsfiddle.net/HhFwL/

You can change the end point, right now it just points to a generic OData end point to fetch some products data. 您可以更改结束点,现在它只是指向一个通用的OData终点来获取一些产品数据。

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

$http.get retuns a HttpPromise Object $ http.get返回一个HttpPromise对象

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

   $scope.data = results;
 })

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

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