AngularJS: инициализировать сервис с асинхронными данными

У меня есть служба AngularJS, которую я хочу инициализировать с некоторыми асинхронными данными. Что-то вроде этого:

myModule.service('MyService', function($http) {
    var myData = null;

    $http.get('data.json').success(function (data) {
        myData = data;
    });

    return {
        setData: function (data) {
            myData = data;
        },
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

Очевидно, это не сработает, потому что если что-то попытается вызватьdoStuff() доmyData возвращается, я получу исключение нулевого указателя. Насколько я могу судить по прочтению некоторых других вопросовВот а такжеВот У меня есть несколько вариантов, но ни один из них не кажется очень чистым (возможно, я что-то упускаю):

Настройка службы с помощью «Выполнить»

При настройке моего приложения сделайте это:

myApp.run(function ($http, MyService) {
    $http.get('data.json').success(function (data) {
        MyService.setData(data);
    });
});

Тогда мой сервис будет выглядеть так:

myModule.service('MyService', function() {
    var myData = null;
    return {
        setData: function (data) {
            myData = data;
        },
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

Это работает некоторое время, но если асинхронные данные занимают больше времени, чем требуется для инициализации всего, я получаю исключение нулевого указателя при вызовеdoStuff()

Используйте обещанные объекты

Это, вероятно, будет работать. Единственный недостаток - везде, где я звоню MyService, я должен знать, что doStuff () возвращает обещание, и весь код будет у насthen взаимодействовать с обещанием. Я предпочел бы просто подождать, пока myData вернется, прежде чем загружать мое приложение.

Ручная начальная загрузка

angular.element(document).ready(function() {
    $.getJSON("data.json", function (data) {
       // can't initialize the data here because the service doesn't exist yet
       angular.bootstrap(document);
       // too late to initialize here because something may have already
       // tried to call doStuff() and would have got a null pointer exception
    });
});

Глобальный Javascript Var Я мог бы отправить свой JSON напрямую в глобальную переменную Javascript:

HTML:

<script type="text/javascript" src="data.js"></script>

data.js:

var dataForMyService = { 
// myData here
};

Тогда это будет доступно при инициализацииMyService:

myModule.service('MyService', function() {
    var myData = dataForMyService;
    return {
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

Это тоже будет работать, но тогда у меня есть глобальная переменная javascript, которая плохо пахнет.

Это мои единственные варианты? Один из этих вариантов лучше, чем другие? Я знаю, что это довольно длинный вопрос, но я хотел показать, что я попытался изучить все мои варианты. Любое руководство будет с благодарностью.

Ответы на вопрос(10)

Ваш ответ на вопрос