angular - 使用 this.http 为 Angular 服务实现 mixin
问题描述
这是 Angular 5 和 typescript 2.9.2
我有一个类是一个服务,它既可以实现 api 又可以作为应用程序中用户故事的状态。一开始它看起来像这样:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/observable';
import { catchError, map, tap } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AuthenticationService } from '../../core/services/authentication.service';
import { HttpErrorService } from '../../core/services/http-error.service';
import { manufacturersUrl } from '../constants';
import { Manufacturers } from '../interfaces/manufacturers.interface';
import { Device } from '../interfaces/device.interface';
@Injectable()
export class LocalService {
public newDevice: Device;
constructor (
private http: HttpClient,
private httpErrorService: HttpErrorService,
private authenticationService: AuthenticationService) {
super();
this.newDevice = {MAC : ''};
}
/**
* getManufacturers api call for first page
* @returns Observable
*/
getManufacturers (): Observable<Manufacturers> {
const requestBody = { 'num': 12 };
return this.http.post<Manufacturers>(manufacturersUrl, requestBody).pipe(
catchError(this.httpErrorService.handleError<Manufacturers>(`getManufacturers`))
);
}
}
如果我的事务代码没有弄乱此服务中的视图,我会更高兴.. 所以我想移动getManufacturers
到./extensionApi.js之类的文件并将其导入以供使用,例如:
import { getManufacturers } from './extensionApi.ts';
//...
private getManufacturers: Function;
constructor (
private http: HttpClient,
private httpErrorService: HttpErrorService,
private authenticationService: AuthenticationService) {
this.newDevice = {MAC : ''};
this.getManufacturers = getManufacturers.bind(this);
}
这种方法可以工作,但在这里不行。我收到一个编译错误:Untyped function calls may not accept type arguments
与this.http
该函数的部分有关。
如何保持设计的模块化,但又能解决编译问题?
附录
这三行完成了下面的答案
constructor(http:HttpClient, httpErrorService: HttpErrorService,
private authenticationService: AuthenticationService) {
super(http, httpErrorService);
执行
本地服务import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AuthenticationService } from '@core/services/authentication.service';
import { HttpErrorService } from '@core/services/http-error.service';
import { Device } from '@usage/interfaces/device.interface';
import ApiClient from './extension-api';
@Injectable()
export class LocalService extends ApiClient {
public newDevice: Device;
constructor(http: HttpClient, httpErrorService: HttpErrorService,
private authenticationService: AuthenticationService) {
super(http, httpErrorService);
this.newDevice = {MAC : ''};
}
}
扩展API
import { Observable } from 'rxjs/observable';
import { catchError, map, tap } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { HttpErrorService } from '@core/services/http-error.service';
import { manufacturersUrl } from '@usage/constants';
import { Manufacturers } from '@usage/interfaces/manufacturers.interface';
/**
* getManufacturers api call for first page
* @returns Observable
*/
export default class ApiService {
constructor (private http: HttpClient,
private httpErrorService: HttpErrorService){}
getManufacturers(): Observable<Manufacturers> {
const requestBody = { 'num': 12 };
return this.http.post<Manufacturers>(manufacturersUrl, requestBody).pipe(
catchError(this.httpErrorService.handleError<Manufacturers>(`getManufacturers`))
);
}
}
解决方案
如果您正在注入HttpClient
,LocalService
那么 HTTP 调用确实应该在该类中进行。使用导入的函数很好,但在这种情况下,它真的混淆了范式,因为你也在函数中绑定了上下文——this
就像使用上下文一样class composition
functional programming
OOD
this
更标准OOD
的方法是扩展具有getManufacturers
函数的基类。基类将注入 HttpClient,并进行post
调用。如果您不打算重用基类,那么它可能不值得
顺便说一句,您的服务的第一个版本看起来绝对是标准的,所以我自己不会更改它
export class BaseService {
constructor(/*inject same classes as LocalService*/) {
}
public getManufacturers (): Observable<Manufacturers> {
.....
}
}
export class LocalService extends BaseService {
constructor(/*inject the dependencies*/) {
super(/* pass the dependencies to the BaseService*/)
}
}
推荐阅读
- javascript - 在角度项目中的数组上设置间隔
- python - 在 localhost 打开但永远保持空白的地方使用 vpython 时出现问题
- scala - Scala 跨项目中的资源
- django - 如何在 django 查询中将表单中的日期与 db 中的日期进行比较?
- django - 在具有嵌套资源的 Tastypie 中,对于给定的 url,获取视图函数名称的最佳方法是什么?
- php - Yii:尽管安装了 memcache/memcached,CMemCache 仍需要加载 PHP memcache 扩展
- python - Python pkg_resources 找不到模块
- postgresql - INSERT 到只有一个串行列的表实际上并没有插入任何东西
- server - 是否可以在 WSL/Linux 上设置 DHCP 服务器?
- sql - ORACLE Pro*C/C++ 代码未对结果进行四舍五入