最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Injecting a resolved promise into service - Stack Overflow

programmeradmin8浏览0评论

I need to get some information (a schema) from the server before I set up a bunch of services that depend on that information.

My server provides a schema that defines various properties of a model. In my angular code, I have a service that gets this schema:

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;
});

I would like to inject the schema object, and not the promise, into other services that depend on the schema. $routeProvider lets us do this for controllers:

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

and this allows me to define SomeCtrl like this:

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

But for services, I have to do:

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

Is there any way I can do this?

I need to get some information (a schema) from the server before I set up a bunch of services that depend on that information.

My server provides a schema that defines various properties of a model. In my angular code, I have a service that gets this schema:

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;
});

I would like to inject the schema object, and not the promise, into other services that depend on the schema. $routeProvider lets us do this for controllers:

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

and this allows me to define SomeCtrl like this:

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

But for services, I have to do:

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

Is there any way I can do this?

Share Improve this question edited Jul 25, 2014 at 3:43 Bergi 666k161 gold badges1k silver badges1.5k bronze badges asked Aug 2, 2013 at 13:51 user2463201user2463201 7352 gold badges7 silver badges11 bronze badges 2
  • Nope, that's just how it works, at least for now. – aet Commented Sep 17, 2013 at 18:54
  • The angular router waits for the values within resolve to resolve/reject before instantiating the controller. Then it uses local values to inject into the controller (the angular injector prefers locals). TL;DR: you're working with two different schemas. – James Kyle Commented Feb 11, 2014 at 20:15
Add a ment  | 

2 Answers 2

Reset to default 5

What you want is deferred bootstrap. There is already a plugin written for this purpose - https://github./philippd/angular-deferred-bootstrap.

I create an example at plunkr - http://plnkr.co/edit/VfISHNULXRLe52NeAsn1?p=preview

*You must replace existing ng-app with deferred bootstrap

Code Snippet -

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

Then, you can use schema anyway in controller, services or factory just like route resolve.

Sample Code for Factory

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

You get a promise because your service function immediately evaluates its body when you call it (as functions do). Normally, a service should return an object so that the consumer (another service, controller, whatever) may then call the functions on that object when it needs to.

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;
  }
}

});

发布评论

评论列表(0)

  1. 暂无评论