处理打字稿代码中的代码重复
Handling code duplication in typescript code
我正在重构一个写得不好的 Angular2 代码,它有如下服务方法:
fooServiceName(body): Observable<any> {
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
return this.http.put(this.loginService.url() + '/url', body, { headers: headers })
.map(response => response.json());
}
barResource(body): Observable<any> {
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
return this.http.post(this.loginService.url() + '/url', body, { headers: headers })
.map(response => response.json());
}
我看到在很多地方重复使用了以下几行:
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
我想写一个单独的方法来调用这些行,但问题是这个项目的新手必须记住调用那个方法,有没有更好的方法?
更新:
添加缺少的方法定义:
/** function to write username and password to local storage of browser*/
public writeAuthToHeaders(headers: Headers): void {
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Basic ' + btoa(getUsername() + ':' + this.getPassword()));
}
最好创建一个 Gloabl service
来共享所有常见的方法,让我们假设您的问题
您可以为整个应用程序创建全局方法来执行与此相同的任务
getHeaders(){
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
return headers;
}
fooServiceName(body): Observable<any> {
return this.http.put(this.loginService.url() + '/url', body, { headers: this.getHeaders() })
.map(response => response.json());
}
barResource(body): Observable<any> {
return this.http.post(this.loginService.url() + '/url', body, { headers: this.getHeaders() })
.map(response => response.json());
}
还尝试为 CRUD 操作创建一些全局方法,以便在将来使用时尝试使用这些方法,而不是每次都创建新方法
只需要将变量作为参数传递,例如 url
、data
等
如果 类 几乎相同,则可以编写复杂类型,并将差异传递给 constructor
。我写了下面的例子:
Generic.Service.ts
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
export class GenericService<T> {
protected http: Http;
constructor(private TCreator: { new (properties: any): T }, private url: string) {}
public get(id: number): Observable<T> {
return this.requestSingle(`${id}`);
}
public getAll(): Observable<T[]> {
return this.requestMultiple('/all.json');
}
private requestSingle(addedUrl?: string): Observable<T> {
return this.request(addedUrl)
.map((response: Response) => new this.TCreator(response.json()));
}
private requestMultiple(addedUrl?: string): Observable<T[]> {
return this.request(addedUrl)
.map((response: Response) => {
const results: any = response.json();
for (let i = 0; i < results.length; i++) {
results[i] = new this.TCreator(results[i]);
}
return results;
});
}
private request(addedUrl?: string): Observable<any> {
return this.http.get(this.url + (addedUrl ? addedUrl : ''));
}
}
用法示例:
Vegetable.Service.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { GenericService } from './generic.service';
import { Vegetable } from '../app.component';
@Injectable()
export class VegetableService extends GenericService<Vegetable> {
constructor(protected http: Http) {
super(Vegetable, '/vegetables');
}
}
Vegetable.ts
interface IVegetable {
id: number;
name: string;
type: string;
}
export class Vegetable implements IVegetable {
public id: number;
public name: string;
public type: string;
constructor(properties: IVegetable) {
this.id = properties.id;
this.name = properties.name;
this.type = properties.type;
}
}
Some.Component.ts
import { Component, OnInit } from '@angular/core';
import { VegetableService } from './services/vegetable.service';
import { IVegetable } from '.components/vegetable.component';
@Component({
selector: 'some-component',
templateUrl: './some.component.html'
})
export class SomeComponent implements OnInit {
public vegetables: IVegetable[] = [];
constructor(private vegetableService: VegetableService) { ... }
public ngOnInit(): void {
...
this.vegetableService.getAll().subscribe((result) => this.vegetables = result);
...
}
}
我正在重构一个写得不好的 Angular2 代码,它有如下服务方法:
fooServiceName(body): Observable<any> {
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
return this.http.put(this.loginService.url() + '/url', body, { headers: headers })
.map(response => response.json());
}
barResource(body): Observable<any> {
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
return this.http.post(this.loginService.url() + '/url', body, { headers: headers })
.map(response => response.json());
}
我看到在很多地方重复使用了以下几行:
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
我想写一个单独的方法来调用这些行,但问题是这个项目的新手必须记住调用那个方法,有没有更好的方法?
更新:
添加缺少的方法定义:
/** function to write username and password to local storage of browser*/
public writeAuthToHeaders(headers: Headers): void {
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Basic ' + btoa(getUsername() + ':' + this.getPassword()));
}
最好创建一个 Gloabl service
来共享所有常见的方法,让我们假设您的问题
您可以为整个应用程序创建全局方法来执行与此相同的任务
getHeaders(){
let headers = new Headers();
this.loginService.writeAuthToHeaders(headers);
return headers;
}
fooServiceName(body): Observable<any> {
return this.http.put(this.loginService.url() + '/url', body, { headers: this.getHeaders() })
.map(response => response.json());
}
barResource(body): Observable<any> {
return this.http.post(this.loginService.url() + '/url', body, { headers: this.getHeaders() })
.map(response => response.json());
}
还尝试为 CRUD 操作创建一些全局方法,以便在将来使用时尝试使用这些方法,而不是每次都创建新方法
只需要将变量作为参数传递,例如 url
、data
等
如果 类 几乎相同,则可以编写复杂类型,并将差异传递给 constructor
。我写了下面的例子:
Generic.Service.ts
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
export class GenericService<T> {
protected http: Http;
constructor(private TCreator: { new (properties: any): T }, private url: string) {}
public get(id: number): Observable<T> {
return this.requestSingle(`${id}`);
}
public getAll(): Observable<T[]> {
return this.requestMultiple('/all.json');
}
private requestSingle(addedUrl?: string): Observable<T> {
return this.request(addedUrl)
.map((response: Response) => new this.TCreator(response.json()));
}
private requestMultiple(addedUrl?: string): Observable<T[]> {
return this.request(addedUrl)
.map((response: Response) => {
const results: any = response.json();
for (let i = 0; i < results.length; i++) {
results[i] = new this.TCreator(results[i]);
}
return results;
});
}
private request(addedUrl?: string): Observable<any> {
return this.http.get(this.url + (addedUrl ? addedUrl : ''));
}
}
用法示例:
Vegetable.Service.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { GenericService } from './generic.service';
import { Vegetable } from '../app.component';
@Injectable()
export class VegetableService extends GenericService<Vegetable> {
constructor(protected http: Http) {
super(Vegetable, '/vegetables');
}
}
Vegetable.ts
interface IVegetable {
id: number;
name: string;
type: string;
}
export class Vegetable implements IVegetable {
public id: number;
public name: string;
public type: string;
constructor(properties: IVegetable) {
this.id = properties.id;
this.name = properties.name;
this.type = properties.type;
}
}
Some.Component.ts
import { Component, OnInit } from '@angular/core';
import { VegetableService } from './services/vegetable.service';
import { IVegetable } from '.components/vegetable.component';
@Component({
selector: 'some-component',
templateUrl: './some.component.html'
})
export class SomeComponent implements OnInit {
public vegetables: IVegetable[] = [];
constructor(private vegetableService: VegetableService) { ... }
public ngOnInit(): void {
...
this.vegetableService.getAll().subscribe((result) => this.vegetables = result);
...
}
}