angular9的学习(十三)

默认把styleExt改成less或者scss

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "angular0629": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"  改这个
        }
      },

命令行创建接口

ng g i  xxx

拦截器

资料

ng g interceptor xxxx
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class ApiInjectorInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    console.log(request);
    return next.handle(request);
  }
}

注册拦截器

app模块
@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
  ],
  declarations: [
    AppComponent,
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: ApiInjectorInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})

如果多个可以这样写

app.mudule.ts

import { httpInterceptorProviders } from "./interceptors";
---
providers: [httpInterceptorProviders],

interceptors/index.ts

import { ConvertInterceptor } from './convert.interceptor';

export const httpInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: NotifyInterceptor, multi: true }
];

拦截请求把https改成http

 intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const httpsReq = request.clone({
      url: request.url.replace("https://", "http://")
    });
    return next.handle(httpsReq);
  }
export class OneComponent{

  constructor(private http:HttpClient) {
  }

  clicks() {
    const url = 'https://jsonplaceholder.typicode.com/comments';
    this.http.get(url).subscribe(res=>{
      console.log(res);
    })
  }
}

或者package.json中

ng serve --ssl
服务使用https请求

添加前缀

req.clone({ 
  url: 'xxxxx' + request.url 
});

或者package.json中

ng server  --base-href xxxxx

添加全局loader

const loaderService = this.injector.get(LoaderService);

loaderService.show();

return next.handle(req).pipe(
  delay(5000),// 模拟延迟5s,开发时候去掉
  finalize(() => loaderService.hide())
    // finalize 完成或者错误时调用一个函数
);

总结完整版

创建加载器服务

services/loader.service.ts

export class LoaderService {
  public isLoading = new BehaviorSubject(false);
  constructor() { }
}

interceptors/loader-interceptor.service.ts

import { Injectable } from '@angular/core';
import {
  HttpResponse,
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { LoaderService } from '../services/loader.service';

@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
  private requests: HttpRequest<any>[] = [];

  constructor(private loaderService: LoaderService) { }
	// 删除加载了的请求
  removeRequest(req: HttpRequest<any>) {
    const i = this.requests.indexOf(req);
    if (i >= 0) {
      this.requests.splice(i, 1);
    }
    this.loaderService.isLoading.next(this.requests.length > 0);
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
	// 添加加载的请求到数组中
    this.requests.push(req);

    console.log("No of requests--->" + this.requests.length);

    this.loaderService.isLoading.next(true);
    return new Observable(observer => {
      const subscription = next.handle(req)
        .subscribe(
          event => {
            if (event instanceof HttpResponse) {
              this.removeRequest(req);
              observer.next(event);
            }
          },
          err => {
            alert('error' + err);
            this.removeRequest(req);
            observer.error(err);
          },
          () => {
            this.removeRequest(req);
            observer.complete();
          });
      // 取消请求时,从队列中删除请求
      return () => {
        this.removeRequest(req);
        subscription.unsubscribe();
      };
    });
  }
}

我们通过请求队列的长度,想loaderService发送true/false

在组件中使用

my-loader.component.html

<div class="progress-loader" [hidden]="!loading">
  加载中
</div>    

my-loader.component.ts

export class MyLoaderComponent implements OnInit {

  loading: boolean;

  constructor(private loaderService: LoaderService) {
    this.loaderService.isLoading.subscribe((v) => {
      this.loading = v;
    });
  }
  ngOnInit() {
  }
}

最后记得在所需要的模块中加上

 providers: [
    LoaderService,
    { provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true }
  ],

修改

我们知道后代有时候传一些属性,我们可以把属性重名名

{
    "Title":'MR',
     "Name":"cool cat",
     "Id":1    
}

改成

{
    "title":'MR',
     "name":"cool cat",
     "id":1    
}

我先写一个简单版,复杂版其实也类似,就是拿到属性进行修改

可以用 lodash的camelCase进行修改

 intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      map((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          // 返回的内容
          let camelCaseObject = Object.entries(event.body).reduce((acc, [key, val]) => {
            acc.push([key.toLocaleLowerCase(), val]);
            return acc;
          }, []);
          console.log(camelCaseObject);
          const modEvent = event.clone({body: Object.fromEntries(camelCaseObject)});

          return modEvent;
        }
      })
    );
  }

在headers 添加标识

const modified = req.clone({ 
  setHeaders: { "X-Man": "Wolverine" } 
});
return next.handle(modified);

拿到请求的标识码

return next.handle(req).pipe(
  tap((event: HttpEvent<any>) => {
    if (event instanceof HttpResponse && event.status === 201) {
        // 提示下,拿到201的标识码啦
      this.toastr.success("Object created.");
    }
  })
);

拦截错误进行处理

next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.status !== 401) {
          console.log('冒泡');
        }
        return throwError(error);
      })
    );

req.method==='GET' // 拿到get请求

模拟请求

//interceptor 里面
if(request.url==='/getList'){
      const body = { firstName: "Mock", lastName: "Faker" };
      return of(new HttpResponse({ status: 200, body: body }));
    }

发的请求
const url='/getList';
    this.http.get(url).subscribe(res=>{
      console.log(res);
    })

添加缓存

export class ApiInjectorInterceptor implements HttpInterceptor {

  private cache = new Map<string, any>();

  constructor() {
  }

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    // 如果不是get请求直接返回
    if (request.method !== 'GET') {
      return next.handle(request);
    }
    const cacheRes = this.cache.get(request.url);
    // 第一次没值
    if (cacheRes) {
      return of(cacheRes);
    }
    return next.handle(request).pipe(
      tap(event => {
        if (event instanceof HttpRequest) {
          this.cache.set(request.url, event);
        }
      })
    );
  }
}

post下载exel表格

  this.http.post('api/s01cross/b04/exportmonfinana', paramMap,
      {responseType: 'blob', observe: 'response'}).subscribe(data => {
      const link = document.createElement('a');
      const blob = new Blob([data.body], {type: 'application/vnd.ms-excel'});
      let fileName = data.headers.get('Content-Disposition').split(';')[1].split('filename=')[1];
      const fileNameUnicode = data.headers.get('Content-Disposition').split('filename*=')[1];
      // 当存在 filename* 时,取filename* 并进行解码(为了解决中文乱码问题)
      if (fileNameUnicode) {
        fileName = decodeURIComponent(fileNameUnicode.split('\'\'')[1]);
      }
      link.setAttribute('href', window.URL.createObjectURL(blob));
      link.setAttribute('download', fileName);
      link.style.visibility = 'hidden';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
posted @ 2020-07-06 11:50  猫神甜辣酱  阅读(579)  评论(0编辑  收藏  举报