资讯专栏INFORMATION COLUMN

Angular2中拦截器Intercept探索之路

instein / 2295人阅读

摘要:初衷之前看到正式发布了,过去看了下,感觉不错,于是入坑。不过思路还是可以借鉴的。尝试以下第一篇链接第二篇链接第三篇里写法过时了按照上述代码,写法与不同,不知道怎么改。

初衷

之前看到angular2正式发布了,过去看了下,感觉不错,于是入坑。
使用过程中想写一个像angular1那样的拦截器,一路坎坷啊

Angular1中的拦截器

</>复制代码

  1. .factory("HttpRequestInterceptor", ["$q", "$injector", "ConfigService", "DialogService", function($q, $injector, ConfigService, DialogService) {
  2. return {
  3. request: function(config) {
  4. if (config.method === "POST") {
  5. config.timeout = 60000;
  6. if (config.data === undefined) {
  7. config.data = {
  8. nologin: 999
  9. };
  10. } else {
  11. config.data.nologin = 999;
  12. }
  13. }
  14. return config;
  15. },
  16. requestError: function(rejection) {
  17. DialogService.alert("发送请求失败,请检查网络");
  18. return $q.reject(rejection);
  19. },
  20. response: function(resp) {
  21. if (resp.data.code !== undefined && resp.data.code !== 0) {
  22. if (resp.data.code === 5003) {
  23. var stateService = $injector.get("$state");
  24. stateService.go("login", {}, {
  25. reload: true
  26. });
  27. } else {
  28. DialogService.alert(resp.data.msg);
  29. }
  30. }
  31. return resp;
  32. },
  33. responseError: function(rejection) {
  34. console.log(rejection);
  35. if (rejection.status === 0) {
  36. DialogService.alert("请求响应错误,请检查网络");
  37. } else if (rejection.status === 500) {
  38. DialogService.alert("服务器出错");
  39. } else {
  40. DialogService.alert("请求失败,请检查网络");
  41. }
  42. return $q.reject(rejection);
  43. }
  44. };
  45. }])
Angular2中没有提供,需要自己实现

去Stackoverflow上搜了好久,有相关内容是不错,但过时了。不过思路还是可以借鉴的。

尝试以下
第一篇链接
第二篇链接
第三篇

</>复制代码

  1. @Injectable()
  2. export class CustomHttp extends Http {
  3. constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
  4. super(backend, defaultOptions);
  5. }
  6. request(url: string | Request, options?: RequestOptionsArgs): Observable {
  7. console.log("request...");
  8. return super.request(url, options).catch(res => {
  9. // do something
  10. });
  11. }
  12. get(url: string, options?: RequestOptionsArgs): Observable {
  13. console.log("get...");
  14. return super.get(url, options).catch(res => {
  15. // do something
  16. });
  17. }
  18. }

app.module.ts里写法过时了

</>复制代码

  1. bootstrap(AppComponent, [HTTP_PROVIDERS,
  2. new Provider(Http, {
  3. useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
  4. deps: [XHRBackend, RequestOptions]
  5. })
  6. ]);

按照上述代码,写法与angular2 r6不同,不知道怎么改。继续搜索,发现大部分写法都雷同,只是注入方式不同,后面看到了r6的注入方式,折腾几次,有了结果

自己的Intercept

customhttp.ts

</>复制代码

  1. import { Injectable } from "@angular/core";
  2. import { Http, Request, RequestOptionsArgs, Response, RequestOptions, ConnectionBackend, Headers } from "@angular/http";
  3. import "rxjs/Rx";
  4. import { Observable } from "rxjs/Observable";
  5. import { PubSubService } from "./shared/pubsub.service";
  6. @Injectable()
  7. export class CustomHttp extends Http {
  8. _pubsub: PubSubService;
  9. constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, pubsub: PubSubService) {
  10. super(backend, defaultOptions);
  11. this._pubsub = pubsub;
  12. }
  13. request(url: string | Request, options ? : RequestOptionsArgs): Observable < Response > {
  14. console.log("good");
  15. return this.intercept(super.request(url, options));
  16. }
  17. get(url: string, options ? : RequestOptionsArgs): Observable < Response > {
  18. return this.intercept(super.get(url, options));
  19. }
  20. post(url: string, body: string, options ? : RequestOptionsArgs): Observable < Response > {
  21. return this.intercept(super.post(url, body, this.getRequestOptionArgs(options)));
  22. }
  23. put(url: string, body: string, options ? : RequestOptionsArgs): Observable < Response > {
  24. return this.intercept(super.put(url, body, this.getRequestOptionArgs(options)));
  25. }
  26. delete(url: string, options ? : RequestOptionsArgs): Observable < Response > {
  27. return this.intercept(super.put(url, this.getRequestOptionArgs(options)));
  28. }
  29. getRequestOptionArgs(options ? : RequestOptionsArgs): RequestOptionsArgs {
  30. if (options == null) {
  31. options = new RequestOptions();
  32. }
  33. if (options.headers == null) {
  34. options.headers = new Headers();
  35. }
  36. options.headers.append("Content-Type", "application/json");
  37. return options;
  38. }
  39. intercept(observable: Observable < Response > ): Observable < Response > {
  40. this._pubsub.beforeRequest.emit("beforeRequestEvent")
  41. observable.subscribe(null, (err) => {
  42. console.log("err");
  43. this._pubsub.afterRequest.emit("afterRequestEvent");
  44. this.handleError(err.status);
  45. }, () => {
  46. console.log("complete");
  47. this._pubsub.afterRequest.emit("afterRequestEvent");
  48. });
  49. return observable;
  50. }
  51. handleError(status) {
  52. if (status === 0) {
  53. this._pubsub.errorToast.emit("请求响应错误,请检查网络");
  54. } else if (status === 404) {
  55. this._pubsub.errorToast.emit("请求链接不存在,请联系管理员");
  56. } else if (status === 500) {
  57. this._pubsub.errorToast.emit("服务器出错,请稍后再试");
  58. } else {
  59. this._pubsub.errorToast.emit("未知错误,请检查网络");
  60. }
  61. }
  62. }

pubsup.service.ts

</>复制代码

  1. import { Injectable } from "@angular/core";
  2. import { Subject } from "rxjs/Subject";
  3. // 发布订阅事件, 继承自Subject, emit用于发射事件
  4. class PubSubEvent extends Subject < String > {
  5. constructor() {
  6. super();
  7. }
  8. emit(value) { super.next(value); }
  9. }
  10. @Injectable()
  11. export class PubSubService {
  12. beforeRequest: PubSubEvent;
  13. afterRequest: PubSubEvent;
  14. errorToast: PubSubEvent;
  15. successToast: PubSubEvent;
  16. showPupup: PubSubEvent;
  17. hidePupup: PubSubEvent;
  18. confirm: PubSubEvent;
  19. constructor() {
  20. this.beforeRequest = new PubSubEvent();
  21. this.afterRequest = new PubSubEvent();
  22. this.errorToast = new PubSubEvent();
  23. this.successToast = new PubSubEvent();
  24. this.showPupup = new PubSubEvent();
  25. this.hidePupup = new PubSubEvent();
  26. this.confirm = new PubSubEvent();
  27. }
  28. }

app.module.ts

</>复制代码

  1. import { NgModule, Injectable } from "@angular/core";
  2. import { BrowserModule } from "@angular/platform-browser";
  3. import { FormsModule } from "@angular/forms";
  4. import { HttpModule, Http, XHRBackend, RequestOptions } from "@angular/http";
  5. // import { InMemoryWebApiModule } from "angular-in-memory-web-api";
  6. import { HeroData } from "./hero/hero-data";
  7. import { routing } from "./app.routing";
  8. import { AppComponent } from "./app.component";
  9. import { CrisisCenterComponent } from "./crisis/crisis-center.component";
  10. import { MapComponent } from "./map/map.component";
  11. import { CustomHttp } from "./customhttp";
  12. import { MapService } from "./map/map.service";
  13. import { PubSubService } from "./shared/pubsub.service";
  14. import { PubSubComponent } from "./shared/pubsub.component";
  15. @NgModule({
  16. declarations: [
  17. AppComponent, CrisisCenterComponent, MapComponent, PubSubComponent
  18. ],
  19. imports: [
  20. BrowserModule,
  21. FormsModule,
  22. HttpModule,
  23. // InMemoryWebApiModule.forRoot(HeroData),
  24. routing
  25. ],
  26. providers: [
  27. MapService,
  28. PubSubService, {
  29. provide: Http,
  30. useFactory: (backend: XHRBackend,
  31. defaultOptions: RequestOptions,
  32. pubsub: PubSubService) => new CustomHttp(backend, defaultOptions, pubsub),
  33. deps: [XHRBackend, RequestOptions, PubSubService]
  34. }
  35. ],
  36. bootstrap: [AppComponent],
  37. })
  38. export class AppModule {}

最后是pubsup.component.ts,我是将loading, toast, pupup放在了一起
loading将在每个请求前显示,请求失败或结束隐藏
toast将在请求失败显示2秒钟,或者在其他组件里调用
pupup将在删除事件前提问,想放在delete api里自动显示并处理,但是没有实现
具体代码在我github:https://github.com/jiangbo201...

</>复制代码

  1. import { Component, Input } from "@angular/core";
  2. import { Http } from "@angular/http";
  3. import { PubSubService } from "./pubsub.service";
  4. @Component({
  5. selector: "app-pubsub",
  6. templateUrl: "./pubsub.component.html",
  7. styleUrls: ["./pubsub.component.css"]
  8. })
  9. export class PubSubComponent {
  10. showloading = false;
  11. showPupub = false;
  12. showSuccessToast = false;
  13. showErrorToast = false;
  14. errorValue: any = "error";
  15. successValue: any = "success";
  16. _pubsub: PubSubService;
  17. constructor(public http: Http, public pubsub: PubSubService) {
  18. this._pubsub = pubsub;
  19. }
  20. cancel() {
  21. this.showPupub = false;
  22. }
  23. confirm() {
  24. this.showPupub = false;
  25. this._pubsub.confirm.emit("confirm");
  26. }
  27. ngOnInit() {
  28. this._pubsub.beforeRequest.subscribe(data => {
  29. console.log(data);
  30. this.showloading = true;
  31. });
  32. this._pubsub.afterRequest.subscribe(data => {
  33. console.log(data);
  34. this.showloading = false;
  35. });
  36. this._pubsub.errorToast.subscribe(data => {
  37. console.log(data);
  38. this.showErrorToast = true;
  39. this.errorValue = data;
  40. let that = this;
  41. // setTimeout(function() {
  42. // console.log(this);
  43. // that.showErrorToast = false;
  44. // }, 2000);
  45. });
  46. this._pubsub.successToast.subscribe(data => {
  47. console.log(data);
  48. this.showSuccessToast = true;
  49. this.successValue = data;
  50. let that = this;
  51. setTimeout(function() {
  52. that.showSuccessToast = false;
  53. }, 2000);
  54. });
  55. this._pubsub.showPupup.subscribe(data => {
  56. this.showPupub = true;
  57. console.log(data);
  58. });
  59. this._pubsub.hidePupup.subscribe(data => {
  60. console.log(data);
  61. this.showPupub = false;
  62. });
  63. }
  64. }

最后,我想在每个删除aip里自动拦截,并弹出提示,如果确定删除就执行,如果放弃就return
但是不知道怎么阻塞执行,欢迎交流

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80661.html

相关文章

  • GMTC 2019 参会回顾

    摘要:回顾上一次参加还是年。年的还是真正的,年的会议早已经把英文全称去掉,改称全球大前端技术大会。同时与产品协作从产品设计方面突出关注点,做产品设计方面的优化,如站新版改造减少页面元素,将播放器窗口直接显示在第一屏。 回顾 上一次参加 GMTC 还是 2017 年。那时的我还是刚刚参加工作并在试用期辞职的菜鸟。 2017 年的 GMTC 还是真正的 Global Mobile Tech Co...

    Zack 评论0 收藏0
  • 2017年2月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...

    lily_wang 评论0 收藏0
  • 2017年2月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...

    chengjianhua 评论0 收藏0
  • 2017年2月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...

    Anonymous1 评论0 收藏0
  • 2017年2月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...

    dreamtecher 评论0 收藏0

发表评论

0条评论

instein

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<