AngularJS загружает данные (настройки) с сервера


Я сделал простое приложение для заказа еды с Laravel 5. Теперь я пытаюсь отделить передний конец и задний конец с помощью AngularJS. Angular захватывает данные из бэк-энда, который представляет собой REST API, основанный на Laravel (Lumen).

В базе данных хранится несколько настроек, состоящих из пары ключ-значение. Подумайте о таких параметрах, как "минимальная сумма заказа" и "стоимость доставки". Обычно я просто вызываю setting(key) в своем приложении Laravel:
/**
 * Get the value for the given setting from the database.
 *
 * @param  mixed  $key
 * @return mixed
 */
function setting($key)
{
    static $settings;

    if(is_null($settings)) {
        $settings = Cache::rememberForever('settings', function() {
            return array_pluck(AppSetting::all()->toArray(), 'value', 'key');
        });
    }

    return (is_array($key)) ? array_only($settings, $key) : $settings[$key];
}

Обратите внимание на статику функции, которые позволяют мне вызывать функцию setting() несколько раз за запрос, но запрашивать базу данных только один раз. Как я могу достичь этого в рамках моего углового приложения?

Я мог бы сделать то же самое с чем-то вроде этого:

/**
 * Retrieve the value of the given setting.
 */
function setting(key) {
        $.get(apiUrl('api/setting'), function(data) use (key) {
            return data.key;
        });
}

...но это приведет к многократным запросам (для одного и того же набора данных) из базы данных, многократно на каждую загруженную страницу. Что довольно неэффективно.

Edit (последний рабочий пример)

app.factory('Setting', ['$q', '$http', function($q, $http) {
    var url = 'api/setting';
    var promise = null;

    function load() {
        if ( ! promise) {
            promise = $q.defer();

            $http.get(apiUrl(url))
                .success(function(data) {
                    promise.resolve(data);
                })
                .error(function(data) {
                    promise.reject(data);
                });
        }

        return promise.promise;
    }

    return {
        load: load
    }
}]);

// Usage
Setting.load().then(function(result) {
    console.log(result);
});
2 3

2 ответа:

Используйте сервис и при необходимости используйте систему кэширования.

angular.factory('SettingsService', SettingsService);

function SettingsService($q, $http) {
    var userUrl = ApiConfigurationService.userUrl;
    var url = 'api/setting';
    var promise = null;

    function loadSettings() {
        if (!promise) {
           promise = $q.defer();

           $http.get('url', function(res) {
                 settings = res.data;
                 promise.resolve(res.data);
            }, function(res) {promise.reject(res)});
        } 
        return promise.promise;
    }

    return {
         loadSettings: loadSettings
     }
}

Затем в вашем контроллере / Директиве

angular.controller('MyController', MyController);

function MyController(SettingsService) {
    var me = this;
    SettingsService.loadSettings(function(res) {
         me.settings = res;});
}

Вы можете использовать функции углового кэширования, описанные здесь: https://docs.angularjs.org/api/ng/service/$http (раздел "кэширование").

Также можно реализовать сервис для значений конфигурации, который загрузит данные один раз, сохранит их локально и предоставит геттер для сохраненного значения.