說明會有哪些常見的服務是所有組件都會用的。
開發過程中會有幾種服務是必然用到的。
-src
|-app
|-app.component.css
|-app.component.html
|-app.component.ts
|-app.module.ts
|-service
|-logger.service.ts
|-web.service.ts
|-data.service.ts
|-user.service.ts
|-login.service.ts
在開發過程中,為了確保後端送來的值以及前端送去的值,
都是要符合API格式去定義的。
為了查驗,多半會在傳接值的部分印log出來看,
但是在系統上線後,這些log都必須拿掉
,
避免營運過程中有心人士看到並做不必要的事情。
專案預設有個 src/environments 資料夾,
是Angular用來動態切換環境的。
//environment.ts
export const environment = {
production: false,
logger: true
};
//environment.prod.ts
export const environment = {
production: true,
logger: false
};
之後系統上線後改參數就可統一拿掉。
一般編譯程式 npm start 會讀取到
environment.ts
,
如果是 npm build --prod
則build出來的網站會讀取environment.prod.ts
,
所以上線時就會看不到logger。
--
logger.service.ts
:import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class LoggerService {
private logger = environment.logger;
log(msg: string) {
if (this.logger) {
console.log(msg);
}
}
error(msg: string) {
if (this.logger) {
console.error(msg);
}
}
print(index: string, msg: any) {
if (this.logger) {
console.log(index, msg);
}
}
}
在需要印log地方,寫上
this.logger.print("response", res)
通常為了跟後端傳值與接值,會做全域型的service來提供
給所有需要資料傳送的功能模塊使用。
與後端做連接的部分,
因目前暫用json-server當 Database,
所以API格式是RESTful。
web.service.ts
:import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs/internal/Observable";
import { of } from "rxjs/internal/observable/of";
import { catchError, tap } from "rxjs/operators";
import { LoggerService } from "./logger.service";
@Injectable({
providedIn: "root"
})
export class WebService {
headers: HttpHeaders;
constructor(private http: HttpClient, private logger: LoggerService) {}
setHeaders(token: string) {
this.headers = new HttpHeaders().set("Authentication", token);
}
getF<T>(url: string): Observable<T[]> {
return this.http.get<T[]>(url, { headers: this.headers }).pipe(
tap(res => this.logger.print("response", res)),
catchError(this.handleError)
);
}
postF<T>(url: string, obj: T): Observable<T> {
return this.http.post<T>(url, obj, { headers: this.headers }).pipe(
tap(res => this.logger.print("post", res)),
catchError(this.handleError)
);
}
delF<T>(url: string): Observable<T> {
return this.http.delete<T>(url, { headers: this.headers }).pipe(
tap(res => this.logger.print("del", res)),
catchError(this.handleError)
);
}
putF<T>(url: string, obj: T): Observable<T> {
return this.http.put<T>(url, obj, { headers: this.headers }).pipe(
tap(res => this.logger.print("put", res)),
catchError(this.handleError)
);
}
patchF<T>(url: string, obj: T): Observable<T> {
return this.http.patch<T>(url, obj, { headers: this.headers}).pipe(
tap(res => this.logger.print("patch", res)),
catchError(this.handleError)
);
}
private handleError(error: Response | any): Observable<any> {
console.error(`${error.status}`);
return of(null);
}
}
最後面的
handleError
網上很多版本,
但是建議即使遇到錯誤,還是需送回一個空值回來。
實務上的流程都會在一開始連接的時候就要設定token,
並且每次的請求都要夾帶token。
當service裡有以下宣告時:
@Injectable({
providedIn: 'root'
})
代表它是整個系統唯一實體,
所以沒有在app.module.ts
裡面註冊也沒關係。
https://stackblitz.com/edit/ngcms-service