AngularJS中的强制服务初始化

时间:2013-10-31 09:12:50

标签: angularjs angularjs-service

我是AngularJS的新手,我正在努力做一些听起来有点微不足道的事情,但我正在努力决定什么是最好的approch。

我在AnuglarJS中有一个服务,它处理我与服务器的所有REST通信。

为了避免在我的客户端/服务器之间更改url名称,我创建了一个名为get_apis的REST API,它负责返回所有apis函数的数组,其中包含的名称为:

{
    'get_user' :'/api/get_user',
    'delete_user' : '/api/delete_user'
}

我遇到的问题是我的所有其他服务/控制器都依赖于此调用,否则在此调用完成之前,APIS将无法用于任何其他休息操作。

假设我正在对我的API服务构造函数执行get_apis rest操作,那么其余的操作仍然是异步的,所以我不能确保我有api。

任何“正确的方法”去做吗?也许我重新映射我的网址的方法是错误的?

4 个答案:

答案 0 :(得分:1)

您可以实现此目的的一种方法是在函数启动时包装需要服务的组件的代码(假设它们在控制器中)。然后在您提到的API服务构造函数中注入$rootScope$rootScope在启动时检索API并使用$broadcast('eventName')调度初始化事件,其他组件(比如控制器)可以在$on('eventName')中通过调用其启动来响应功能。

编辑:如果我正确理解了问题,这是一个Fiddle来证明这一点。

答案 1 :(得分:1)

没有简单的解决方案,因为您的应用需要在正确初始化之前进行异步调用。

有几种解决方案。

  1. 将所需数据注入应用程序的主模板。假设您有一个模板index.html,它由您的后端提供,并包含所有脚本。您的后端可以包含一个带有api功能的脚本。当你想到它时,你的生产代码中的api不会经常更改,因此每次app启动时都会发出api函数调用没有意义。相反,您使用api维护一个静态.json或.js文件,并将其包含在html本身中。函数名称将在应用程序启动时准备好。

  2. 在你的应用程序的.config或.run块中进行异步调用,延迟所有正常操作,直到获取api函数列表。这是维护的噩梦,因为每次使用api的操作都必须首先检查布尔标志或监听事件或依赖promise来确保api函数列表已准备好。

  3. 使用角度路由机制(我更喜欢ui-state模块),定义在“/”位置初始化的顶级/根/主路由或状态,并添加api函数调用,因为它在解析列表中依赖。

  4. 我不确定这是否可以使用通用路由,但是使用状态你可以这样做:

    .config(['$stateProvider'], function($stateProvider) {
       $stateProvider.state('main', {
          resolve: {
            apis: ['APIService', function(APIService) {
              return APIService.getApis();
            }]
          }
       }).state('someState', {
          parent: 'main',
          ...
       })
      ...
     })
    

    所有其他状态将依赖于'main',并且在api函数列表准备好之前,它们都不会被初始化。

答案 2 :(得分:0)

我不确定我是否完全理解了这个问题,但如果你只是想在一个中心位置为你的REST调用定义URL,以便所有服务都可以使用它,那么我会做类似的事情

angular.module('myApp', [])
  .constant('REST_API_URLS', (function () {
      return {
        'get_user' :'/api/get_user',
        'delete_user' : '/api/delete_user'
      };
    })()
  )
  .service('MyRESTService', function ($http, REST_API_URLS) {
    $http.get(REST_API_URLS.get_user)
    .success() // etc
  });

答案 3 :(得分:0)

除了其他答案,您应该了解手动AngularJS引导,如下所述:API reference / angular.bootstrap 您可以找到一些可能性的比较,包括angular.bootstrap here的示例。

我们使用另一种方法,使用专用的初始化服务来配置我们的应用程序,并强制我们的控制器等待其他控制器或服务完成其初始化任务。我们可以在blog找到非常详细的说明,并在AngularJS forum开始讨论。代码以jsfiddle提供,在您的控制器中看起来像这样:

init('userCtrl', [apiResolutionService.getApiUrls()], function(result) {
    var apiUrls = result[0].data.apiUrls;
    var user = $http.get(apiUrls.get_user, ...);
});