2013-08-02 50 views
12

我需要從服務器獲取一些信息(模式),然後才能設置一組依賴於該信息的服務。將已解決的承諾注入服務

我的服務器提供了一個模式來定義模型的各種屬性。在我的角度代碼,我應該得到這個模式的服務:

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

是有什麼辦法可以做到這一點?

+0

都能跟得上

示例代碼,這只是它是如何工作的,至少目前如此。 – aet

+0

在實例化控制器之前,角度路由器等待「resolve」內的值解析/拒絕。然後它使用本地值注入控制器(角度注入器更喜歡本地)。 TL; DR:你正在使用兩個不同的'模式'。 –

回答

-1

你得到了一個承諾,因爲你的服務函數在你調用它時會立即評估它的正文(就像函數那樣)。通常情況下,服務應該返回一個對象,以便消費者(另一個服務,控制器,任何)可以在需要時調用該對象上的函數。

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

在你的例子中,'get'方法仍然返回一個promise,而不是promise的分辨率,這就是問題所在。 –

5

你想要的是延期引導。已經有一個爲此編寫的插件 - 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'); 
       } 
      ] 
     } 
    }); 
}); 

然後,您可以在控制器反正使用架構,服務或工廠就像路由解析一樣。工廠

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

準確地說,我也在尋找,謝謝 - 延期的bootstrapping就像一個魅力的組件! – conceptdeluxe