AngularJS - 在单个 AJAX 调用中检索多个小部件的数据

AngularJS - Retrieving Data for Multiple Widgets in a Single AJAX Call

我有一个关于多个小部件的数据检索的架构问题。

我正在使用 AngularJS 构建大型 javascript 应用程序(迷你 SPA)。我想创建一个非常模块化的仪表板应用程序,其中包含交互式小部件,用户可以选择在布局系统的容器中包含、排除或重新定位这些小部件。用户可以与每个小部件进行交互,从而单独刷新其数据等等。每个小部件将显示与其他小部件截然不同的数据。


到目前为止,在架构上,每个小部件都将由这些 AngularJS 组件表示:

因此每个小部件都能够通过调用特定端点的 Angular 服务提取自己的数据。

现在,当用户到达可能包含 5 个小部件的仪表板页面时,我不想对 5 个不同的服务器端点进行 5 个单独的并行 AJAX 调用。那是没有效率的;我想减少对服务器的并行请求。

相反,在到达页面时,我宁愿通过调用聚合了 5 个小部件的所有数据的端点来进行单个 AJAX 调用。

问题: 假设服务器可以 bundle/merge 1 JSON 有效载荷中的 5 个小部件的所有数据在一个聪明的包装器中,然后在AngularJS 应用程序,我如何检索该数据并将其分发给 5 个小部件控制器,以便它们可以使用新的服务器数据进行自我初始化?

当然,我想保留任何单个小部件仅刷新自身的能力。虽然超出仪表板页面的行为不是我在这个问题中要问的。

也许外面有文章谈到这个,但我还没有找到一篇。


我已经想到了一个我认为“好”的架构想法,但我想知道是否有更好的解决方案。

可能性)除了进行 AJAX 调用的 5 个 Angular 服务外,还引入了第 6 个称为 WidgetAggregateService 的服务。当它的 retrieveAllAndBroadcast() 方法被执行时,该服务将自己处理成功回调,然后使用 $rootScope.$emit() 将负载发布到 5 个控制器。因此,WidgetAggregateService 将在 $rootScope 上使用 Mediator 模式(或 PubSub 模式),5 个控制器可以使用 $rootScope.$on() 订阅。每个小部件的控制器都可以获取聚合数据有效负载中的相关信息。

我和我的团队想出了一个解决方案……

API合同

我们开发了一个 API 合约,允许我们向服务器请求 1 个或多个小部件(包括传递相关的请求参数),这将 return 1 个或多个小部件响应JSON 包装器。因此我们可以通过以下方式进行检索:

  • 单个小部件检索
  • 多个(聚合)小部件检索 - 我们一次请求 2 个或更多小部件的数据。

对服务器的一次调用。


通过聚合检索将数据传送到小部件控制器

1) 聚合检索:我们有一个 AngualrJS“页面”控制器,负责在页面加载时对页面上的所有小部件进行聚合检索。它通过将 AJAX 请求委托给 Ng 工厂来处理数据检索来请求页面上的所有 5 个小部件——我们称之为“PageResourceFactory”。

2) Forward to Individual Widget ResourceFactories: 在成功取回“PageResourceFactory”数据后,它会调用另一个工厂助手将相关响应转发给调用的各个小部件资源工厂他们的设定方法。因此至此,所有5个widget资源工厂都有了他们的数据集。

3) 小部件控制器订阅新数据:在页面初始化期间,每个小部件控制器已经设置了对自己资源工厂的订阅,以便在设置新数据时进行实质监听(通过他们的资源工厂设置方法)。因此,控制器可以知道数据何时更改(无论小部件控制器是否启动检索)。

4) Widget Controllers Bind Data:每个 widget controller 都会收到数据更改的“通知”,因此可以通过将其放在作用域中以绑定到视图来做出相应的响应.

单次检索

这只是一个标准的 AJAX 检索。
1) 控制器通过资源工厂发出请求。

2) 资源工厂借助 $http 执行 AJAX 请求并将承诺对象传回控制器。

3) 控制器获取数据(在成功调用 promise 之后)并将其绑定以供视图显示。


这就是我们解决问题的方式。我确定还有其他可能性。