FireBase推出最新的雲端資料庫的版本(cloud Firestore), 有別之前的RealTime的資料庫,更引進rxjs的oberserable和subscription的模式,讓程式更具有高彈性,我們就簡單的實作範例。
一、建立Colud Firestore
選擇下拉式選單è Cloud Firestore
二、引用firestore
安裝angularfire2
npm install angularfire2 –save
import { AngularFireModule } from 'angularfire2';
import {AngularFirestoreModule} from 'angularfire2/firestore';
新版的colud
firestore的設定檔需要加上projectId
// AF2 Settings
export const firebaseConfig =
{
apiKey: "xxxxxxxxxxx",
authDomain: "fiyy4.firebaseapp.com",
databaseURL: "https://firstapp-xxxx.firebaseio.com",
projectId: "fyyyy4",
storageBucket: "firstyy.appspot.com",
messagingSenderId: "1233456789"
};
注入AngularFireModule和AngularFirestoreModule
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
AngularFireModule.initializeApp(firebaseConfig),
AngularFirestoreModule
],
三、ProvideràMoney_service.ts建立CRUD的函式
AngularFirestoreCollection
用來取得資料列表(查詢)
AngularFirestoreDocument
用來允許編輯/刪除資料
Observable
用來取得資料陣列有更新的值
import { Observable } from 'rxjs/Observable';
import { AngularFirestore,
AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
宣告
valueChange: 傳回Json的物件,不具有metadata的屬性
export class
MoneyServiceProvider {
itemCollections:
AngularFirestoreCollection<any>; //資料庫傳回值型態
items:
Observable<any[]>;
constructor(public afs: AngularFirestore) {
this.itemCollections
= this.afs.collection('moneyCost', ref =>
ref.orderBy('costDate')); //取回資料庫moneyCost,並依日期排序
this.items = this.itemCollections.valueChanges();//取回值
}
新增
snapshotChanges:可以用來異動資料庫,本身具有metadata的屬性
public add(item) {
this.itemCollections.add(item);
const listObservable
= this.itemCollections.snapshotChanges()
}
刪除
AngularFirestoreDocument:取回Firestore Collection 的物件
public remove(itemID) {
const itemDoc:
AngularFirestoreDocument<any> = this.afs.doc<any>('moneyCost/' + itemID);
itemDoc.delete();
}
List:取得id
public list() {
return this.itemCollections.snapshotChanges().map(actions
=> {
return
actions.map(a => {
const data =
a.payload.doc.data() as any;
data.id =
a.payload.doc.id;
return data;
});
});
}
整理陣列的資料 data[key]=[{},{}]
public groupList(items:any[]){
let total=0;
const
groupItem=[];
items.forEach(eachObj
=> {
if(groupItem[eachObj.costDate]
== undefined){
groupItem[eachObj.costDate]=[];
}
total=+eachObj.cost;
groupItem[eachObj.costDate].push({key:eachObj.costDate,
value:eachObj,sum:total});
});
return groupItem;
}
Reduce:累加器,會自動依序陣陣值取出作運算後,傳回最終結果
public getCostSum(items):Observable<number>
{
// return
1000;
return
items.map((items: any[]) => {
return items.reduce((prev,
curr: any) => {
return prev +
Number(curr.cost);
}, 0);
})}
四、建立Componentàmoney-list.ts
import { MoneyServiceProvider } from '../../providers/money-service/money-service';
import { AngularFirestore, AngularFirestoreCollection
} from 'angularfire2/firestore';
宣告物件
interface money {
productId:
string;
costDate: string;
cost: number;
}
export class
MoneyListComponent implements OnDestroy {
private subscription:
ISubscription;
itemCollections:
AngularFirestoreCollection<money>;
items:any[];
obserItem:Observable<any[]>;
groupList: any[];
sumCost: Number;
constructor(public afs:
AngularFirestore, public moneyService: MoneyServiceProvider) {
this.obserItem=
moneyService.list(); //取回資料
this.obserItem.subscribe(x=>{
//將取回來的值放回到變數中,透過item 在畫面上呈現
this.items=x;
this.groupList
=moneyService.groupList(this.items);
this.doSum (this.items); //計算總合
});
}
}
//累加器,會自動傳回最後值的運算結果
doSum(items) {
this.items.reduce((prev,
curr: any) =>{
return this.sumCost =
prev + Number(curr.cost);
} ,0);
}
doDelete(itemId:
any) {
this.moneyService.remove(itemId);
//刪除document
}
ngOnDestroy() {
//解除訂閱
this.obserItem.subscribe().unsubscribe();
}
}
Component: money-list.html
建立group pipe 呈現複雜資料結構
data[key]=[{},{}],轉換資料結構 [{key:1,value=data},{key:2,value=data}]
@Pipe({
name: 'group',
})
export class GroupByPipe implements
PipeTransform {
transform(value:
any, args: any[] = null): any {
let keys = [];
for (let key in value) {
keys.push({
key: key, value: value[key] });
}
return keys;
}
}
加上關鍵字group 就會將資料置換{key,value}
<ion-list>
<ion-item-group *ngFor="let
item of groupList|group">
<ion-item-divider color="light">
<h3>
<font color=black>{{item.key|date}}</font>
</h3>
</ion-item-divider>
<ion-item *ngFor="let
subItem of item.value">
<ion-row>
<ion-col col-lg-4>
<font color=blue>{{subItem.value.productId}}</font>
</ion-col>
<ion-col col-lg-4>
<font>{{subItem.value.cost|currency}}
</font>
</ion-col>
<ion-col col-lg-4>
<button ion-button color="danger" small round (click)="doDelete(subItem.value.id)">刪除</button>
</ion-col>
</ion-row>
</ion-item>
</ion-item-group>
<h1><font color=red>總額<input type="hidden" [(ngModel)]="sumCost"> {{sumCost}}</font></h1>
</ion-list>
範例如下
新增
列表
以上總結 Colud
Firestore 可以讓資料傳回時,可先轉換資料型態/結構/運算值…等等,更具有彈性。
沒有留言:
張貼留言