先前開發 Dashboard 的時候,大部份取得資料的邏輯都寫在 controller,但那是因為當時會的還不多,所以不讓情境變得太複雜,而事實上:
Service 可以分為幾類
接下來將透過一個股票交易的程式來示範如何建立 Service
這支程式會用到多個 Service
首先,先去下方的連結取得一個初步的框架
npm install
ng serve
那麼就來建立第一個 Service 吧
這個 Service 會管理帳戶相關的問題,例如持有多少股票,帳戶中還有多少資金…等
不過打開 VSCode 一看 account.service.ts 已經存在了,如果是自己從頭建起的專案的話,就會是透過以下的指令:
# 完整版
ng generate service account
# 懶人版
ng g s account
既然有了 Service,自然是要實作它,程式碼如下:
import { Injectable } from '@angular/core'
import { Stock } from './stocks.model';
const defaultBalance: number = 10000;
@Injectable()
export class AccountService {
private _balance: number = defaultBalance;
private _cost: number = 0;
private _value: number = 0;
private _stocks: Stock[] = [];
get balance(): number { return this._balance; }
get cost(): number { return this._cost; }
get value(): number { return this._value; }
get stocks(): Stock[] { return this._stocks; }
purchase(stock: Stock): void {
stock = Object.assign({}, stock);
if (stock.price < this.balance) {
this._balance = this.debit(stock.price, this.balance);
stock.cost = stock.price;
this._cost = this.credit(stock.price, this.cost);
stock.change = 0;
this._stocks.push(stock);
this.calculateValue();
}
sell(index: number): void {
let stock = this.stocks[index];
if (stock) {
this._balance = this.credit(stock.price, this.balance);
this._stocks.splice(index, 1);
this._cost = this.debit(stock.cost, this.cost);
this.calculateValue();
}
init() {
}
reset() {
this._stocks = [];
this._balance = defaultBalance;
this._value = this._cost = 0;
}
calculateValue() {
this._value = this._stocks
.map(stock => stock.price)
.reduce((a, b) => { return a + b }, 0);
}
private debit(amount: number, balance: number): number {
return (balance * 100 - amount * 100) / 100;
}
private credit(amount: number, balance: number): number {
return (balance * 100 + amount * 100) / 100;
}
}
實作了 Service,就是要使用它
import { Component, OnInit, OnDestroy } from '@angular/core';
import { AccountService } from './services/account.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
constructor(private accountService: AccountService) {}
// ...(略)
reset(): void {
this.accountService.reset();
}
// ...(略)
}
前面有提到,要成為 service 的類別都必須要加上 Injectable(),但那只是其中一個條件,另一個條件是要在 app.module.ts 註冊這個 service
// ...(略)
@NgModule({
declarations: [
AppComponent,
// ...(略)
],
imports: [
BrowserModule,
// ...(略)
],
providers: [
// ...(略)
AccountService,
// ...(略)
],
bootstrap: [AppComponent]
})
export class AppModule { }
小結