เพิ่ม HTTP Interceptors หลายตัวใน Angular Application


86

จะเพิ่มตัวดักจับ HTTP อิสระหลายตัวลงในแอปพลิเคชัน Angular 4 ได้อย่างไร

ฉันพยายามเพิ่มโดยขยายprovidersอาร์เรย์ที่มีตัวสกัดกั้นมากกว่าหนึ่งตัว แต่สุดท้ายเท่านั้นที่ถูกดำเนินการจริงInterceptor1จะถูกละเว้น

@NgModule({
  declarations: [ /* ... */ ],
  imports: [ /* ... */ HttpModule ],
  providers: [
    {
      provide: Http,
      useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
        new Interceptor1(xhrBackend, requestOptions),
      deps: [XHRBackend, RequestOptions],
    },
    {
      provide: Http,
      useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
        new Interceptor2(xhrBackend, requestOptions),
      deps: [XHRBackend, RequestOptions]
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

เห็นได้ชัดว่าฉันสามารถรวมเข้าเป็นInterceptorชั้นเรียนเดียวได้และน่าจะได้ผล อย่างไรก็ตามฉันต้องการหลีกเลี่ยงเนื่องจากตัวดักจับเหล่านี้มีจุดประสงค์ที่แตกต่างกันโดยสิ้นเชิง (อันหนึ่งสำหรับการจัดการข้อผิดพลาดอันหนึ่งเพื่อแสดงตัวบ่งชี้การโหลด)

ฉันจะเพิ่มตัวดักจับหลายตัวได้อย่างไร


2
Httpคุณกำลังเอาชนะ ใช้การแทนที่สุดท้ายเท่านั้น Interceptor1 ไม่ถูกละเว้นมันเป็นเพียงแค่ไม่มีอยู่จริง คุณสามารถใช้ HttpClient ที่มี interceptors รวมอยู่ด้วย
Estus Flask

@estus คุณหมายถึงอะไรโดย "คุณสามารถใช้ HttpClient ที่มี interceptors รวมอยู่ด้วย"?
str


คุณสามารถใช้ตัวสกัดกั้นที่แตกต่างกันสำหรับการร้องขอการตอบสนองโดยใช้สิ่งนี้ที่คุณสามารถจัดการข้อผิดพลาดตัวบ่งชี้ตัวโหลด
nivas

มีการอัปเดตเกี่ยวกับคำถามนี้หรือไม่?
Renil Babu

คำตอบ:


164

Httpไม่อนุญาตให้มีการใช้งานแบบกำหนดเองมากกว่าหนึ่งรายการ แต่อย่างที่ @estus กล่าวถึงทีม Angular ได้เพิ่มบริการHttpClientใหม่เมื่อเร็ว ๆ นี้ (รุ่น 4.3) ซึ่งรองรับแนวคิดตัวสกัดกั้นหลายตัว คุณไม่จำเป็นที่จะขยายที่คุณทำกับเก่าHttpClient Httpคุณสามารถจัดเตรียมการใช้งานHTTP_INTERCEPTORSแทนซึ่งสามารถเป็นอาร์เรย์ด้วย'multi: true'ตัวเลือก:

import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
...

@NgModule({
  ...
  imports: [
    ... ,
    HttpClientModule
  ],
  providers: [
    ... ,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorOne,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorTwo,
      multi: true,
    }
  ],
  ...
})

ตัวสกัดกั้น:

import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
...

@Injectable()
export class InterceptorOne implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('InterceptorOne is working');
    return next.handle(req);
  }
}

@Injectable()
export class InterceptorTwo implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('InterceptorTwo is working');
    return next.handle(req);
  }
}

การเรียกเซิร์ฟเวอร์นี้จะพิมพ์ข้อความบันทึกของผู้สกัดกั้นทั้งสอง:

import {HttpClient} from '@angular/common/http';
...

@Component({ ... })
export class SomeComponent implements OnInit {

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.http.get('http://some_url').subscribe();
  }
}

4
มีวิธีใดที่จะบอกapiว่าสามารถดักฟังได้เพียงวิธีเดียวinterceptor? หรือโดยเงื่อนไขใด ๆ ?
k11k2

@ k11k2 และสำหรับทุกคนที่ค้นหานี่คือคำถามและคำตอบเกี่ยวกับสิ่งนี้: stackoverflow.com/questions/45781379/…ฉันยอมรับว่าฉันยังสับสนอยู่เล็กน้อย
trollkotze

ทำไมต้องเป็น @Injectable ()? มันใช้งานได้โดยไม่ต้องมี @Injectable () สำหรับฉัน
มักกาซี

1
@makkasi: ต้องเพิ่ม @ Injectable ถ้าคลาส interceptor ต้องทำการฉีดแบบพึ่งพาของตัวเอง ในตัวอย่างที่กำหนดไม่จำเป็น
jintoppy

1
@ AmirReza-Farahlagha Interceptors ถูกเรียกตามลำดับที่ให้ไว้
hiper2d
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.