Вопрос

The problem I have is that on page load the response from the API takes a while and my view (scope) is empty. But when I switch view back and forth the groups-view (scope) is updated with the object which was loaded from the API on page load.

I want to be able to load all my data and have it available in all views at all time and for it to dynamically update the first view (scope) on page load when the data becomes available.

I guess this is possible, but what am I missing?

My service:

angular.module('myApp.services', [])
.service('groups', function ($http) {
    var groups = [];

    // Load the data once from the API
    if(!groups.length) {
        $http.get('/api/groups')
            .then(
                function(response) {
                    groups = response.data;
                }
            );
    }

    return {
        // For update if new data is available
        setData: function(arr) {
            groups = arr;
        },
        // Return all groups
        getAll: function () {
            return groups;
        },
        // Get a given group name
        getNameById: function (id) {
            for(var i = 0; i < groups.length; i++) {
                if(groups[i].id === id) {
                    return groups[i].name;
                }
            }
            return null;
        },
        // Get a given group short name
        getShortNameById: function (id) {
            for(var i = 0; i < groups.length; i++) {
                if(groups[i].id === id) {
                    return groups[i].short_name;
                }
            }
            return null;
        },
        getTeamsById: function (id) {
            for(var i = 0; i < groups.length; i++) {
                if(groups[i].id === id) {
                    return groups[i].team_ids;
                }
            }
            return null;
        }
    };
});

My controller:

function GroupsOverviewCtrl($scope, groups) {
    // Populate the scope with data
    $scope.groups = groups.getAll();
}
GroupsOverviewCtrl.$inject = ['$scope', 'groups'];
Это было полезно?

Решение

The "Angular way" of dealing with async operations is promises instead of callbacks.
This is what it might look like:

.factory('groups', function ($http, $q) {
    var groups = [],

    return {
        setData: function(arr) {
            groups = arr;
        },
        getAll: function () {
            if(groups.length) {
                return $q.when(groups);
            } else {
                return $http.get('/api/groups').then(function (response) {
                    groups = response.data;
                    return groups;
                });
            }
        },
        getNameById: function (id) {...},
        getShortNameById: function (id) {...},
        getTeamsById: function (id) {...}
    };
});

function GroupsOverviewCtrl($scope, groups) {
    groups.getAll().then(function (data) {
        $scope.groups = data;
    });
}
GroupsOverviewCtrl.$inject = ['$scope', 'groups'];

Другие советы

Ok, so I think I've fixed it... getting late here and my brain is shutting down. The answer was to use a callback (as always with http request).

The service:

angular.module('myApp.services', [])
.factory('groups', function ($http) {
    var groups = [],
        groupsObj = {
            setData: function(arr) {
                groups = arr;
            },
            getAll: function () {
                return groups;
            },
            getNameById: function (id) {
                for(var i = 0; i < groups.length; i++) {
                    if(groups[i].id === id) {
                        return groups[i].name;
                    }
                }
                return null;
            },
            getShortNameById: function (id) {
                for(var i = 0; i < groups.length; i++) {
                    if(groups[i].id === id) {
                        return groups[i].short_name;
                    }
                }
                return null;
            },
            getTeamsById: function (id) {
                for(var i = 0; i < groups.length; i++) {
                    if(groups[i].id === id) {
                        return groups[i].team_ids;
                    }
                }
                return null;
            }
        };

    return {
        get: function(callback) {
            if(!groups.length) {
                $http.get('/api/groups')
                    .then(
                        function(response) {
                            groups = response.data;

                            callback(groupsObj);
                        }
                    );
            } else {
                callback(groupsObj);
            }
        }
    };
});

The controller:

function GroupsOverviewCtrl($scope, groups) {
    groups.get(function(groupsObj) {
        $scope.groups = groupsObj.getAll();
    });
}
GroupsOverviewCtrl.$inject = ['$scope', 'groups'];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top