精通 MEAN 当 MEAN 遇到 Meetup.com 和微数据(7)
 
- UID
- 1066743
|

精通 MEAN 当 MEAN 遇到 Meetup.com 和微数据(7)
创建一个服务比较 与 AngularJS 用于发出原始 HTML 请求,比如 GET、POST、PUT 和 DELETE。在发出一次性请求时使用此服务。 是一种更高级的便捷服务,用于管理模型对象上的完整 CRUD 生命周期。可使用更低级的 $http 服务执行类似的操作,但如果在处理模型时使用 $resource 服务,最终编写的自定义代码就少得多。用于创建完整 CRUD 模块的 Yeoman 生成器使用了 $resource 服务。要查看它的实际应用,请浏览 public/modules/articles/services/articles.client.service.js。
使用了一个 AngularJS 来发出 Ajax 请求,这是与外部 Meetup.com API 进行交互的完美解决方案。
您可能想要直接从控制器发出 Ajax 请求,但这么做有点目光短浅。如果其他控制器中需要该活动数据,该怎么办?您肯定不想在控制器之间复制和粘贴源代码,对吧?为了方便跨多个控制器共享相同数据,可创建一个服务。
键入 yo meanjs:angular-service events 来创建一个 events 服务,如清单 12 所示。在提示时选择 events 模块。
清单 12. 生成一个 AngularJS 服务1
2
3
4
5
6
7
8
9
10
| $ yo meanjs:angular-service events
[?] Which module does this service belongs to?
articles
core
events
talks
users
create public/modules/events/services/events.client.service.js
|
AngularJS 提供了一个名为 $http 的预构建服务来发出 HTTP/Ajax 请求。(所有 AngularJS 服务都有一个 $ 前缀。)要使用 $http,需将它注入到您的服务中。在 events 服务能正常运行后,将它注入到 EventsController 中。(AngularJS 到处都使用了依赖性注入。)
还记得您在 EventsController 中使用的 $scope 对象吗?$scope 是一个注入到控制器中的服务。如清单 13 所示,注入 $scope 服务的方式是,声明它,然后将它以参数形式传递给函数。
清单 13. 注入 $scope 服务1
2
3
4
5
6
7
| 'use strict';
angular.module('events').controller('EventsController', ['$scope',
function($scope) {
$scope.title = 'High Performance WebSocket';
}
]);
|
两次键入服务名称似乎有点多余,但这么做方便了在准备将 MEAN 应用程序部署到生产环境中时发生的精简和串联过程。
您已看到如何注入一个服务,是时候应用这一知识了。打开 public/modules/events/services/events.client.service.js,如清单 14 所示。
清单 14. public/modules/events/services/events.client.service.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 'use strict';
angular.module('events').factory('Events', [
function() {
// Events service logic
// ...
// Public API
return {
someMethod: function() {
return true;
}
};
}
]);
|
注入 $http 服务,如清单 15 所示。
清单 15. 注入 $http 服务1
2
3
4
5
6
7
8
9
10
11
12
13
| angular.module('events').factory('Events', ['$http',
function($http) {
// Events service logic
// ...
// Public API
return {
someMethod: function() {
return true;
}
};
}
]);
|
接下来,将 someMethod 更改为 getNextEvent 并删除一些基本功能的存根,如清单 16 所示。
清单 16. 从 Ajax 调用返回 JSON1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| 'use strict';
angular.module('events').factory('Events', ['$http',
function($http) {
// Public API
return {
getNextEvent: function() {
var url = 'http://api.meetup.com/2/events?status=upcoming&order=
time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&desc=
false&offset=0&photo-host=public&format=json&page=1&fields=
&sig_id=13848777&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&callback=JSON_CALLBACK';
var request = $http.jsonp(url);
return request;
}
};
}
]);
|
(详细的)URL 将返回 HTML5 Denver User Group 的下一场即将举办的活动。(Meetup.com 提供了一个很好的 来使用其 API。)如果将该 URL 复制到您的浏览器中,您将获得完整的 JSON 响应。为清楚起见,我编辑了该响应,如清单 17 所示。
清单 17. 来自 Meetup.com 的 API 的 JSON 响应1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| {
"results": [
{
"status": "upcoming",
"visibility": "public",
"venue": {
"id": 21506832,
"name": "Rally Software",
"state": "CO",
"address_1": "1550 Wynkoop",
"city": "Denver"
},
"id": "160326502",
"time": 1411430400000,
"event_url": "http:\/\/www.meetup.com\/HTML5-Denver-Users-Group\/events\/160326502\/",
"description": "<p><b>6 pm : \"Developing Offline Applications with HTML 5\"
by Venkat Subramaniam<\/b><\/p> ",
"name": "\"Developing Offline Applications\" and \"HTML 5 Animations\""
}
],
"meta": {
"count": 1,
"total_count": 3,
"next": "http:\/\/api.meetup.com\/2\/events?status=upcoming&sig_id=13848777&
order=time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&
desc=false&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&photo-host=public&offset=1&
format=json&page=1&fields="
}
}
|
结果数组中的 JSON 对象看起来应很熟悉。您删除了 EventsController 中的类似数据。但请注意,完整的 JSON 响应包含其他对在主页上呈现数据没有必要的信息(比如 meta)。幸运的是,在传递 JSON 响应之前可对它执行转换。将转换逻辑添加到 events 服务,如清单 18 所示。
清单 18. 转换 JSON 响应1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| // Public API
return {
getNextEvent: function() {
var url = 'http://api.meetup.com/2/events?status=upcoming&order=
time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&desc=
false&offset=0&photo-host=public&format=json&page=1&fields=
&sig_id=13848777&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&callback=JSON_CALLBACK';
var returnFirstElement = function (data, headers) {
return data.results[0];
};
var request = $http.jsonp(url, {transformResponse: returnFirstElement});
return request;
}
};
}
]);
|
有了转换逻辑,JSON 将仅包含来自结果数组的第一个元素。所有其他额外的 JSON 信息都会丢弃。
为了在开发过程中提供帮助,可添加 success 和 error 处理函数,如清单 19 所示。此代码会将响应数据记录到控制台。您可自由地定义此代码,或者完全忽略它。
清单 19. 添加 success 和 error 处理函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| // Public API
return {
getNextEvent: function() {
var url = 'http://api.meetup.com/2/events?status=upcoming&order=
time&limited_events=False&group_urlname=HTML5-Denver-Users-Group&desc=
false&offset=0&photo-host=public&format=json&page=1&fields=
&sig_id=13848777&sig=7aa5d53f450ee5449945e8ee89b8cba8968d9e30&callback=JSON_CALLBACK';
var returnFirstElement = function (data, headers) {
return data.results[0];
};
var request = $http.jsonp(url, {transformResponse: returnFirstElement});
request.success(function(data, status, headers, config) {
console.log('SUCCESS');
console.log(data);
});
request.error(function(data, status, headers, config) {
console.log('ERROR');
console.log(data);
});
return request;
}
};
}
]);
|
现在 events 服务已完成,可以将它注入到 EventsController 中。修改 EventsController,如清单 20 所示。
清单 20. 将 events 服务注入到 EventsController 中1
2
3
4
5
6
7
8
9
10
11
| 'use strict';
angular.module('events').controller('EventsController', ['$scope', 'Events',
function($scope, Events) {
$scope.event = undefined;
Events.getNextEvent().success(function(data){
$scope.event = data;
});
}
]);
|
如果所有功能都按预期运行,您应在主页上看到一段完整的活动描述,如图 8 所示。如果在演讲描述中看到了比之前模拟的更多的细节,就会知道一切正常。
图 8. 完整、有效的示例的实际应用 |
|
|
|
|
|