Внедрение разрешенных обещаний в эксплуатацию

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

Мой сервер предоставляет схему, которая определяет различные свойства модели. В моем коде angular у меня есть служба, которая получает эту схему:

services.factory('schema', function($q, $http) {
    var deferred = $q.defer();
        $http.get('schema/').then(function(response) {
        schema = // some function of response.data
        deferred.resolve(schema);
    }, function() {
        deferred.reject('There was a problem fetching the schema');
    }); 
        return deferred.promise;
});

Я хотел бы добавить объект схемы, а не обещание, в другие службы, которые зависят от схемы. $routeProvider позволяет нам делать это для контроллеров:

app.config(function($routeProvider) {
    $routeProvider.
        when('/', {
            controller: 'SomeCtrl',
            resolve: {
                schema: 'schema'
            },
            ...
        });
});

и это позволяет мне определить SomeCtrl следующим образом:

controllers.controller('SomeCtrl', function($scope, schema) {
    // schema is an object
    ...
});

Но для сервисов я должен делать:

services.factory('SomeService', function(schema) {
    // schema is a promise
    schema.then(function(schema) {
        ...
    });
});

Можно ли мне это сделать?

Ответ 1

Что вы хотите, так это отложенный бутстрап. Для этой цели уже создан плагин - https://github.com/philippd/angular-deferred-bootstrap.

Я создаю пример на plunkr - http://plnkr.co/edit/VfISHNULXRLe52NeAsn1?p=preview

* Вы должны заменить существующее ng-приложение отложенным бутстрапом

Фрагмент кода -

angular.element(document).ready(function() {
    deferredBootstrapper.bootstrap({
        element: document.body,
        module: 'plunker',
        resolve: {
            schema: ['$http',
                function($http) {
                    return $http.get('schema.json');
                }
            ]
        }
    });
});

Затем вы можете использовать схему в любом случае в контроллере, службах или factory точно так же, как и решение маршрута.

Пример кода для factory

app.factory('SomeService', function(schema){
    return {
        getTitle: function() {
            return schema.title;
        }
    }
});

Ответ 2

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

services.factory('schema', function($q, $http) {
return {
  get: function() {
    var deferred = $q.defer();
    $http.get('schema/').then(function(response) {
      schema = // some function of response.data
      deferred.resolve(schema);
    }, function() {
      deferred.reject('There was a problem fetching the schema');
    });
    return deferred.promise;
  }
}

});