与angularjs $ http函数同步

时间:2015-01-03 18:33:50

标签: angularjs http asynchronous promise

我是angularjs的新手,我有一个非常小的应用程序,可以从我的服务器加载联系人。这里的代码片段是完整的app.js. 问题是我无法弄清楚如何使用同步进行服务器调用。在代码片段中,当我刷新页面时,显示警报3,然后警告2,然后最终警报4.由于服务器http调用需要一些时间,因此函数立即返回。所以我在浏览器中得到的是数组中的2个测试项目的显示" contacts"。警报4终于出现了,但为时已晚。任何帮助将不胜感激。



var module = angular.module('app', []);

module.service('ContactService', function ($http) {

    //contacts array to hold list of all contacts - 2 entries for test

    //var $contacts = [];
    var contacts = [
        {
        id: 0,
        'First_Name': 'Harmon',
        'Last_Name': 'Adams',
        'Home_Phone': '123-2343-44'
        },
        {
            id: 1,
            'First_Name': 'Sam',
            'Last_Name': 'Spade',
            'Home_Phone': '123-2343-44'
        }
    ];

    // returns the contacts list
    this.list = function () {
    //    var contacts = [];
        $http.post('http://localhost/Contacts7/GetData.php', {'cat' : 'Friends'}).
            success(function(data)  {
                contacts =  data.datarecords;
                alert('4 - within $post - '+contacts);
            }).
            error(function(data, status){
                alert('error!');
            });
        alert('3 - before return - '+contacts);
        return contacts;
    }
});

module.controller('ContactController', function ($scope, ContactService ) {
    $scope.contacts = ContactService.list();
    alert('2 - after list - '+ $scope.contacts);
});

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title>Contact Dialer </title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link href="css/style.css" rel="stylesheet">
</head>
<body>
<div ng-app="app" ng-controller="ContactController">

    <div class="container" >
    <div class="row row-centered">
        <div class="col-md-2 button-row col-centered">
            <button type="button" class="btn btn-Primary btn-l btn-block" ng-click="GetByCat('Favorites')">Favorites</button>
        </div>
        <div class="col-md-2 button-row col-centered">
            <button type="button" class="btn btn-Primary btn-l btn-block" ng-click="GetByCat('Friends')">Friends</button>
        </div>
        <div class="col-md-2 button-row col-centered">
            <button type="button" class="btn btn-Primary btn-l btn-block" ng-click="GetByCat('Loose Friends')">Loose Friends</button>
        </div>
        <div class="col-md-2 button-row col-centered">
            <button type="button" class="btn btn-Primary btn-l btn-block" ng-click="GetByCat('Loose_Loose Friends')">Loose-Loose Friends</button>
        </div>
        <div class="col-md-2 button-row col-centered">
            <button type="button" class="btn btn-Primary btn-l btn-block" ng-click="GetByCat('Business')">Business</button>
        </div>
        <div class="col-md-2 button-row">
        </div>
    </div>
        {{xxx}}
        <table class='table table-striped table-bordered'>
            <th class = 'text-center'>Name</th>
            <th class = 'text-center'>Home Phone</th>
            <th class = 'text-center'>Mobile Phone</th>
            <th class = 'text-center'>Bus. Phone</th>
            </tr>
            <tr ng-repeat='contact in contacts'>
                <th class = 'text-center' >{{contact.Last_Name}}, {{contact.First_Name}}</th>
                <td class = 'text-center'>{{contact.Home_Phone}}</td>
                <td class = 'text-center'>{{contact.Mobile_Phone}}</td>
                <td class = 'text-center'>{{contact.Business_Phone}}</td>
            </tr>
        </table></div>
    </div>
<script src="js/jquery-1.11.0.min.js"></script>
<script src="js/underscore-min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="js/app.js"></script>
</body>
</h
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

您无法从服务返回contacts,因为将异步确定联系人。相反,您需要为联系人返回承诺,您可以使用这些联系人来填充控制器的联系人。

服务:

module.service('ContactService', ['$http', function ($http) {
    return {
        list: function () {
            return $http.post('http://localhost/Contacts7/GetData.php', 
                              {'cat' : 'Friends'})
            .then(function (response) {
                return response.data.datarecords;
            })
            .catch(function (error) {
                throw new Error("Failed to retrieve contacts!");
            });
        }
    };
}]);

注意您可能已经注意到我将第一行从使用魔法依赖注入样式更改为使用数组样式依赖注入。这只是我个人的偏好(因为我认为神奇的DI风格是一个坏主意),而不是你必须要做的事情。这同样适用于以下代码。

控制器:

module.controller('ContactController', ['$scope', 'ContactService',
                                        function ($scope, ContactService ) {
    $scope.contacts = [];
    ContactService.list()
    .then(function (contacts) {
        $scope.contacts = contacts;
        alert('2 - after list - '+ $scope.contacts);
    });
}]);

答案 1 :(得分:0)

不要从ajax外部返回联系人对象。 它应该是从其成功回调返回联系人对象。

// returns the contacts list
this.list = function () {
//    var contacts = [];
$http.post('http://localhost/Contacts7/GetData.php', {'cat' : 'Friends'}).then(
//success call back
function(data)  {
    contacts =  data.datarecords;
    alert('4 - within $post - '+contacts);
    return contacts;
},
//error call back
function(data, status){
    //error handling can be done here
    alert('error!');
    return;
});

希望这可能对你有所帮助。