使用Angular构建动态http服务
我有一个Ionic应用程序,这个应用程序包含一组页面和服务,现在因为我在使用Ionic&Angular,我决定为不同的项目构建可重用的代码 例如,Http服务:在这个服务中,我想集中管理与服务器端通信的代码,以实现可重用的概念,并且更改将集中在一个地方 我的Http.service代码是:使用Angular构建动态http服务,angular,ionic-framework,service,Angular,Ionic Framework,Service,我有一个Ionic应用程序,这个应用程序包含一组页面和服务,现在因为我在使用Ionic&Angular,我决定为不同的项目构建可重用的代码 例如,Http服务:在这个服务中,我想集中管理与服务器端通信的代码,以实现可重用的概念,并且更改将集中在一个地方 我的Http.service代码是: export interface RequestOptions { observable?: any; url?:string; method?: string; successCallBac
export interface RequestOptions {
observable?: any;
url?:string;
method?: string;
successCallBack?: any;
notSuccessCallBack?: any;
useDefaultNotSuccessCallBack?: boolean;
errorCallBack?: any;
useDefaultErrorCallBack?: boolean;
completeCallBack? : any;
sendToken?: boolean;
data?: any;
refresher?:Refresher;
infinitScroller?: InfiniteScroll;
loader?: Loading;
}
export interface ForkOptions {
requests: RequestOptions[];
useDefaultNotSuccessCallBack?: boolean;
errorCallBack?: any;
useDefaultErrorCallBack?: boolean;
completeCallBack? : any;
refresher?:Refresher;
infinitScroller?: InfiniteScroll;
loader?: Loading;
}
import {Injectable} from "@angular/core";
import {AuthenticationService} from "./authentication.service";
import {Observable} from "rxjs/Observable";
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {AlertController, InfiniteScroll, Loading, Refresher} from "ionic-angular";
import 'rxjs/add/observable/forkJoin';
@Injectable()
export class HttpConnectionService {
constructor(
private http: HttpClient,
private authService: AuthenticationService,
private alertCtrl: AlertController
) {}
/**
* @param {ForkOptions} options: an options which contains the list of requests to be forked together.
* this method will construct an array of observables and handle the response using @responseHandler and @errorHandler methods
* in this service
*/
httpRequests( options: ForkOptions) {
// build the array of observables
let observables = [
...options.requests.map((request) => request.observable)
];
// subscribe to these observables
Observable.forkJoin(observables).subscribe(
(results) => {
// handle the response for each of the requests
for(let i = 0; i < results.length; i++) {
this.responseHandler(results[i], options.requests[i]);
}
}, (error) => {
// handle the errors
this.errorHandler(error, options);
}, () => {
// execute the complete handler
this.completeHandler(options);
}
);
}
/**
* @param {RequestOptions} requestOptions: contains the options and attributes of the request to be constructed
* @returns {any} return a ready to subscribe observable
*/
createObservable(requestOptions: RequestOptions) {
// switch statement to handle the different types of methods.
switch(requestOptions.method) {
// if the case is post or delete method, they would have the same parameters.
case 'post' : case 'delete' :
return this.postDelete(requestOptions);
// if the case is get method, it will be constructed differently
case 'get':
return this.get(requestOptions);
}
}
/**
*
* @param {RequestOptions} requestOptions: the options and attribute of the request (post or delete)
* @returns {any}: return the request observable.
*/
private postDelete(requestOptions: RequestOptions) {
return this.http[requestOptions.method](requestOptions.url, requestOptions.data);
}
/**
*
* @param {RequestOptions} requestOptions
* @returns {Observable<Object>}
*/
private get(requestOptions: RequestOptions) {
return this.http.get(requestOptions.url);
}
/**
*
* @param {RequestOptions} requestOptions identify different attributes of the request.
*/
httpRequest(requestOptions: RequestOptions) {
// send the http request and use the method attribute
// if there is observable sent with request
let observable = requestOptions.observable;
if(observable == undefined){
// if there is no observable, create one
observable = this.createObservable(requestOptions);
}
observable.subscribe(
(response: any) => {
// call the response handler
this.responseHandler(response, requestOptions);
}, (error) => {
// call the error handler
this.errorHandler(error, requestOptions);
}, () => {
// call the complete handler
this.completeHandler(requestOptions);
}
);
}
private responseHandler(response, requestOptions: RequestOptions) {
// if the response success, execute the success call back
if(response.isSuccess) {
requestOptions.successCallBack(response.result);
// check if there is infinit scroller and the response is empty, then disable the infinit scroller
if(requestOptions.infinitScroller && response.result.length == 0) {
requestOptions.infinitScroller.enable(false);
}
}else {
// if the response is not success, check if the notSuccessCallBack is defined,
// if notSuccessCallBack is defined, execute it, other wise, execute the default notSuccess callBacl
if(requestOptions.notSuccessCallBack) {
// execute the provided not success callBack
requestOptions.notSuccessCallBack(response);
}else if(requestOptions.useDefaultNotSuccessCallBack){
// execute the default not success callBack
this.defaultNotSuccessResponse(response);
}
}
}
private errorHandler(error, requestOptions: RequestOptions | ForkOptions) {
// check for the provided error callBack.
if(requestOptions.errorCallBack) {
// execute the provided callBack
requestOptions.errorCallBack(error);
}else if(requestOptions.useDefaultErrorCallBack){
// if u can default error handler
this.defaultErrorHandler(error, requestOptions);
}
}
/**
*
* @param {RequestOptions | ForkOptions} requestOptions: the requests options which contain completeCallBack.
*/
private completeHandler(requestOptions: RequestOptions | ForkOptions) {
// if there is complete callBack, execute it.
if(requestOptions.completeCallBack) {
requestOptions.completeCallBack();
}
// turn off the external components after the response is arrived
// for example: loader, infinit scroller, refreshing
this.turnOffExternalComponents(requestOptions);
}
/**
* contains the default behavioral for the not success response,
* it can be terminated if @useNotSuccessResponse = false in the request options.
* @param response: the response from the server side which contains the error message.
*/
private defaultNotSuccessResponse(response) {
// the default behavioral is to display an error message.
this.alertCtrl.create({
title: "Error!",
subTitle: response.message
}).present();
}
/**
*
* @param error: the error object
* @param {RequestOptions} requestOptions: contains attributes about the request
* used as params to access the external components when turning them off.
*/
private defaultErrorHandler(error, requestOptions: RequestOptions | RequestOptions | ForkOptions) {
// turn off the active components.
this.turnOffExternalComponents(requestOptions);
// create alert for the client.
this.alertCtrl.create({
title: "Error!",
subTitle: error.message
}).present();
}
/**
* terminates the view components which are related to the request,
* @param {RequestOptions | ForkOptions} requestOptions
*/
private turnOffExternalComponents(requestOptions: RequestOptions | ForkOptions) {
// set the refresher to complete
if(requestOptions.refresher) {
requestOptions.refresher.complete();
// after refreshing, enable the infinit scroller.
if (requestOptions.infinitScroller) {
requestOptions.infinitScroller.enable(true);
}
}
// set the infinit Scroller to complete.
// and turn on the infinit scroller.
if(requestOptions.infinitScroller) {
requestOptions.infinitScroller.complete();
}
// check if there is loader, and turn it off.
if(requestOptions.loader) {
requestOptions.loader.dismissAll();
}
}
}
导出接口请求选项{
可观察?:任何;
url?:字符串;
方法?:字符串;
成功回调?:任何;
notSuccessCallBack?:任何;
useDefaultNotSuccessCallBack?:布尔值;
错误回调?:任何;
useDefaultErrorCallBack?:布尔值;
completeCallBack?:任何;
sendToken?:布尔值;
数据?:任何;
复习者?:复习者;
无限卷轴?:无限卷轴;
装载机?:装载;
}
导出接口选项{
请求:请求选项[];
useDefaultNotSuccessCallBack?:布尔值;
错误回调?:任何;
useDefaultErrorCallBack?:布尔值;
completeCallBack?:任何;
复习者?:复习者;
无限卷轴?:无限卷轴;
装载机?:装载;
}
从“@angular/core”导入{Injectable}”;
从“/authentication.service”导入{AuthenticationService};
从“rxjs/Observable”导入{Observable};
从“@angular/common/http”导入{HttpClient,HttpHeaders};
从“离子角度”导入{AlertController,InfiniteScroll,Loading,Refresher};
导入“rxjs/add/observable/forkJoin”;
@可注射()
导出类HttpConnectionService{
建造师(
私有http:HttpClient,
私有authService:AuthenticationService,
私有alertCtrl:AlertController
) {}
/**
*@param{ForkOptions}options:一个包含要分叉在一起的请求列表的选项。
*此方法将构造一个观察值数组,并使用@responseHandler和@errorHandler方法处理响应
*在这项服务中
*/
httpRequests(选项:ForkOptions){
//构建可观察的数组
设可观测项=[
…options.requests.map((请求)=>request.observable)
];
//同意这些观察结果
可观察的。forkJoin(可观察的)。订阅(
(结果)=>{
//处理每个请求的响应
for(设i=0;i{
//处理错误
this.errorHandler(错误,选项);
}, () => {
//执行完整的处理程序
this.completeHandler(选项);
}
);
}
/**
*@param{RequestOptions}RequestOptions:包含要构造的请求的选项和属性
*@returns{any}返回准备订阅的可观察
*/
createObservable(请求选项:请求选项){
//switch语句来处理不同类型的方法。
开关(requestOptions.method){
//如果案例是post或delete方法,则它们将具有相同的参数。
案例“发布”:案例“删除”:
返回此.postDelete(requestOptions);
//如果案例是get方法,那么它将以不同的方式构造
案例“get”:
返回此.get(requestOptions);
}
}
/**
*
*@param{RequestOptions}RequestOptions:请求的选项和属性(post或delete)
*@returns{any}:返回可观察的请求。
*/
私有postDelete(请求选项:请求选项){
返回此.http[requestOptions.method](requestOptions.url,requestOptions.data);
}
/**
*
*@param{RequestOptions}RequestOptions
*@returns{Observable}
*/
私有get(requestOptions:requestOptions){
返回this.http.get(requestOptions.url);
}
/**
*
*@param{RequestOptions}RequestOptions标识请求的不同属性。
*/
httpRequest(请求选项:请求选项){
//发送http请求并使用method属性
//如果存在与请求一起发送的可观测数据
让observable=requestOptions.observable;
如果(可观察==未定义){
//如果没有可观察的,创建一个
observable=this.createObservable(请求选项);
}
可观察的(
(答复:任何)=>{
//调用响应处理程序
this.responseHandler(响应,请求选项);
},(错误)=>{
//调用错误处理程序
this.errorHandler(错误,请求选项);
}, () => {
//调用完整的处理程序
this.completeHandler(requestOptions);
}
);
}
私有responseHandler(响应、请求选项:请求选项){
//如果响应成功,则执行成功回调
if(response.issucess){
requestOptions.successCallBack(response.result);
//检查是否有无限滚动条且响应为空,然后禁用无限滚动条
if(requestOptions.infiniteScroller&&response.result.length==0){
requestOptions.infiniteScroller.enable(false);
}
}否则{
//如果响应不成功,请检查是否定义了notSuccessCallBack,
//如果定义了notSuccessCallBack,则执行它,否则执行默认的notSuccess callBacl
if(requestOptions.notSuccessCallBack){
//执行提供的not success回调
requestOptions.notSuccessCallBack(响应);
}else if(requestOptions.useDefaultNotSuccessCallBack){
//执行默认的not success回调
此.defaultNotSuccessResponse(响应);
}
}
}
私有errorHandler(错误,requestOptions:requestOptions | ForkOptions){
//检查提供的错误回调。
if(requestOptions.errorCallBack){
//执行提供的回调
requestOptions.errorCallBack(错误);
}else if(requestOptions.useDefaultErrorCallBack){
//如果您可以使用默认的错误处理程序
this.defaultErrorHandler(错误,请求选项);
}
}
/**
*
*@param{RequestOptions
public errors = new ReplaySubject<any>(1);
public void doRequest(): Observable<any> {
this._http.get('').catch((err, source) => {
this.errors.next(err);
return source;
});
}
public ngOnInit() {
this._httpService.errors.subscribe(error => {
this.scrollerEnabled = false;
})
}