0

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

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

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

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

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

假设我在我的 API 服务构造函数上执行 get_apis 休息操作,但休息操作仍然是异步的,所以我不能确保我有 api。

有什么“正确的方法”吗?也许我重新映射我的网址的方法是错误的?

4

4 回答 4

1

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

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

于 2013-10-31T10:24:36.940 回答
1

There is no simple solution since your app needs to make async call before it is properly initialized.

There are several solutions.

  1. Inject required data into main template of the app. Let's say you have a template index.html, which is served by your backend and where all scripts are included. Your backend could include one more script with your api functions. When you think of it, your api in the production code will not change frequently, therefore issuing a call for api functions everytime app starts does not make sense. Instead, you maintain a static .json or .js file with your apis and include it in the html itself. Function names would be ready at app boot time.

  2. Make async call in .config or .run block of your app delaying all normal operations until api function list is fetched. This is maintenance nightmare because every single operation with api must first check a boolean flag or listen for event or depend on promise to be sure api function list is ready.

  3. Using angular routing mechanisms (I prefer ui-state module), define top-level/root/main route or state that is initialized on "/" location and add api function call as it's dependency in resolve list.

I'm not really sure if this is possible with generic routes, but with states you could do something like this:

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

All other states would depend on 'main' and none of them would be initialized before your api functions list is ready.

于 2013-10-31T11:41:27.920 回答
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
  });
于 2013-10-31T10:51:28.253 回答
0

除了其他答案之外,您还应该了解此处所述的手动 AngularJS 引导:API 参考 / angular.bootstrap您可以在此处 找到一些可能性的比较,包括 angular.bootstrap 的示例。

我们使用另一种方法和专用初始化服务来配置我们的应用程序,并强制我们的控制器等待其他控制器或服务完成它们的初始化任务。可以在我们的博客上找到非常详细的描述,AngularJS论坛已经开始了一些讨论。该代码可作为jsfiddle使用,并且在您的控制器中看起来像这样:

init('userCtrl', [apiResolutionService.getApiUrls()], function(result) {
    var apiUrls = result[0].data.apiUrls;
    var user = $http.get(apiUrls.get_user, ...);
});
于 2013-10-31T20:49:31.777 回答