使用AngularJS获取异步数据

时间:2017-12-07 15:35:51

标签: angularjs asynchronous

我正在设计一个公司页面,其中根据当前登录的用户加载一些页面元素。例如,如果公司登录我的应用程序并想要在仪表板中查看其帐户详细信息,则仪表板页面将加载该公司的特定元素(名称,描述等)。 我的问题是,当我加载页面时,我的数据没有绑定到我的vm变量。但是,检查控制台我发现我的数据确实正在被服务检索,稍后会发现。以下是我弄清楚的方法:

(function () {
'use strict';

angular.module('mainApp')
    .controller('currentCompanyCtrl',CurrentCompanyController);
CurrentCompanyController.$inject = ['CompanyService','AlertService', 'AuthService','$routeParams','$http'];
function CurrentCompanyController(CompanyService, AlertService, AuthService, $routeParams) {
    var vm = this;

    console.log(vm.company); //returns undefined
    vm.internships = getInternshipsByLoggedId();
    vm.company = getCompanyByLoggedId();
    console.log(vm); //returns two undefined objects
    for(var x in vm){
        console.log(x);
    }
    //todo find out why vm doesn't get filled earlier, probably has to do with asynchronous calls
    //do I need to return a Promise??

    //this returns the current company with the id provided by the current logged company
    //and binds it to the vm.company object
    function getCompanyByLoggedId() {
        AuthService.getCompany().then(
            function(response) {
                CompanyService.getCompanyById(response.data.id).then(
                        function success(response) {
                            vm.company = response.data;
                            console.log(response.data); //this returns the company
                        },
                        function error(response) {
                            vm.serverErrors = response.data;
                            AlertService.alertError(response.data);
                        });
            });
    }
....

proof

稍后出现的是我在getCompanyByLoggedId函数中执行的console.log。

这意味着数据检索正在服务中异步处理,我应该返回一个Promise - 我可以从Google中读取/收集。 我尝试从角度使用$ q,但无济于事。我需要修改我的服务吗?目前它们如此:

(function () {
'use strict';

angular.module('mainApp')
    .factory('AuthService', AuthService);

AuthService.$inject = ['$http'];
function AuthService($http) {
    var service = {};

    service.getUser = getUser;
    service.getStudent = getStudent;
    service.getCompany = getCompany;

    return service;


    function getUser() {
        return $http.post('/api/user');
    }
    function getStudent() {
        return $http.post('/api/student');
    }
    function getCompany() {
        return $http.post('/api/company');
    }
}
})();

(function () {
'use strict';

angular.module('mainApp')
    .factory('CompanyService', CompanyService);

CompanyService.$inject = ['$http'];
function CompanyService($http) {
    var service = {};

    service.getCompanyById = getCompanyById;
    service.getById = getById;
    return service;

    function getCompanyById(id) {
        return $http.get('api/companies/'+id);
    }

    function getById(id) {
        return $http.get('api/companies/'+id+'/internships');
    }
}
})();

所以基本上我希望能够将数据绑定到我的vm对象,以便我可以在我的页面中显示它。如果我的数据仅在以后到达,我该怎么做?

1 个答案:

答案 0 :(得分:1)

这里你没有什么问题。您没有返回值

首先你可以做这样的事情,回归,也许你会得到价值。 (可能?有时会有2-3秒的延迟,至少我已经在我的情况下看到了它)

getCompanyByLoggedId().then((data)=>{vm.company = data});

....
//Return your promises and make a chain of it
function getCompanyByLoggedId() {
    return AuthService.getCompany().then(
        function(response) {
            return CompanyService.getCompanyById(response.data.id).then(
                    function success(response) {
                        return response.data;
                    },
                    function error(response) {
                        AlertService.alertError(response.data);
                        return response.data;
                    });
        });
}

我做什么?我使用$ q.defer,你可以在这里阅读https://docs.angularjs.org/api/ng/service/$q

getCompanyByLoggedId().then((data)=>{vm.company = data});
....

function getCompanyByLoggedId() {
    var defer = $q.defer();//Create a defer obj which will return when resolved or rejected
    AuthService.getCompany().then(
        function(response) {
            CompanyService.getCompanyById(response.data.id).then(
                    function success(response) {
                        defer.resolve(response.data);
                    },
                    function error(response) {
                        AlertService.alertError(response.data);
                        defer.reject(response.data);
                    });
        });
       return defer.promise;
}