具有多个API数据服务的应用程序
Application with multiple API data services
我正在尝试设计一个Angular应用程序,它的组件注册了一个回调函数和一个'数据请求对象'与Angular服务。该服务基本上跟踪所有数据请求对象以及它们引用的回调函数。然后,它执行长轮询以对RESTful API进行异步调用。当所有数据都传入时,服务决定哪些组件需要哪些数据片段,并使用API调用的结果调用它们。
我有麻烦的问题是,每个组件可能需要将数据"转换"成规定为特定格式的JSON对象。例如,图表组件可能要求数据结果以一种方式显示,但表组件可能要求数据结果以另一种方式显示。
为了使事情变得更加复杂,我想以这样一种方式设计我的数据服务,即组件可以注册来自多个不同的RESTful api的数据。
由于我对Angular相当陌生,所以我想获得一些关于完成这类应用的最佳实践的帮助。我想做的是有一个"主"数据服务,我的组件注册。注册函数将接受一个回调函数和一个数据请求对象作为参数,格式如下:
{
"service": "apiService",
"request": {
...
}
}
那么每个RESTful API都会有一个单独的Angular服务。这些子服务将处理如何处理数据请求对象,并对应于上面的"service"字段。然后,主数据服务将在一个较长的轮询周期中将请求排队到子服务。所以主数据服务看起来像这样(注意:我使用的是ES6):
class DataService {
constructor($q, $interval, $injector) {
this.$q = $q;
this.$interval = $interval;
this.$injector = $injector;
this.subscriptions = [];
this.callbacks = [];
this.poll();
}
poll() {
let reqs = [];
angular.forEach(this.subscriptions, (sub, i) => {
let service = this.$injector.get(sub.service);
let deferred = this.$q.defer();
reqs.push(deferred);
service.get(sub.request).then((result) => {
this.callbacks[i](result);
deferred.resolve(result);
}, (result) => {
deferred.reject(result);
});
});
this.$q.all(reqs).then(() => {
this.$interval(poll, this.pollInterval || 10000);
});
}
register(request, callback) {
this.subscriptions.push(request);
this.callbacks.push(callback);
}
}
angular.module('DataService', []).service('DataService', DataService);
我有麻烦弄清楚如何实现的那块是"数据转换"块。据我所知,实际上只有两个地方可以看到这个数据转换发生:
- 组件内部
- 单个API服务内部
第一种方式对我来说似乎不是一个可行的选择,因为它打破了组件应该有点"愚蠢"的惯例。组件不应该处理转换RESTful API返回的数据:它应该按原样使用数据。
但是第二种方法也带来了另一个问题,那就是每个RESTful API服务都必须为我创建的每个组件类型具有转换函数。这在我看来似乎不"干净"。
是否有其他方法可以设计我的应用程序来实现这个目标?
一个建议:使用angular内置的事件系统。
//Constructor
constructor($q, $interval, $injector, $rootScope) {
this.$q = $q;
this.$interval = $interval;
this.$injector = $injector;
this.$rootScope = $rootScope;
this.listeners = [];
//No idea how its written in Angular2 but cleanup the event listeners when this is destroyed
//Example in 1.5.x:
//$scope.$on('$destroy', () => angular.forEach(this.listeners, l => l());
this.poll();
}
//The new register method
register(ev, callback) {
//When cleaning up - iterate over listeners and invoke each destroy function - see constructor
this.listeners.push(this.$rootScope.$on(ev, callback));
}
//The new poll method
poll() {
let reqs = [];
angular.forEach(this.subscriptions, (sub, i) => {
let service = this.$injector.get(sub.service);
let deferred = service.get(sub.request).then((response) => {
//responseToEventsMapper should map and parse response to list of events to fire.
//Lets say the response is an authentication response for login attempt,
//then the triggered events will be 'Auth:stateChange' and 'Auth:login' with
//response.user as data. configure responseToEventsMapper upfront.
let events = this.responseToEventsMapper(response);
angular.forEach(events, event => this.$rootScope.$emit(event.type, event.data));
});
reqs.push(deferred);
});
this.$q.all(reqs).then(() => {
this.$interval(poll, this.pollInterval || 10000);
});
}
- Redux应用程序结构-在哪里放置服务/业务逻辑
- Sails.js:我可以将一些服务/模型打包为npm并在Sails.jss应用程序中加载npm吗
- 使用connect vhost为多个express.js应用程序提供服务
- 通过共享服务在两个不同ng应用程序中的控制器之间共享数据
- 如何创建可从多个应用程序使用的PHP登录web服务
- 谷歌应用程序脚本html服务和加载谷歌地图javascript api V3
- 如何使应用程序加载独立于web服务调用
- angular应用程序中的浏览器功能检测:使用服务、指令、控制器
- Rails 4 应用程序 - Heroku / Cloudfront - 资产无法从源正确服务
- 谷歌应用程序脚本:使用mailapp.sendmail服务发送只有偶尔附件的邮件
- HTML5 Metro应用程序是否可能使用PHP中的web服务
- 应用程序脚本高级驱动器API服务-newFile()方法未创建文件
- 如何检查我是否使用java服务登录到外部应用程序
- 将node.js应用程序作为服务移植并部署到windows
- 它有一个库或Web服务,可以为我的javascript应用程序提供夏令时数据
- $q服务 - 我应该在新的 AngularJS 应用程序中使用 CommonJS 风格还是构造函数风格
- 开发两个单独的节点应用程序来提供 Web 服务和使用 Web 服务以在浏览器上呈现它是一个好主意吗?
- 如何在服务应用程序后在视图中加载 js.js
- 如何配置WCF服务应用程序
- 找到最近的标记到一个新的标记添加客户服务应用程序