我有一个firestore数据库,它的集合排列类似于相关集合中的关系数据库,存储外键。做出此决定是为了使与现有.NET服务的集成更容易,并允许更大的灵活性。
以下是数据模型的一部分:
我已经将我的状态划分为功能模块,并有如下代码:
ngxsoninit(ctx:stateContext<schedulesstatemodel>){
调度()
新建getscheduleGroups(),
新建GetSchedules()
)
}
@选择()
静态计划组(状态:schedulesstatemodel):数组<schedulegroup>。{
返回state.schedulegroups;
}
@选择()
静态scheduleGroupByID(状态:schedulesstatemodel){
返回(scheduleGroupID:string)=>。{
return state.scheduleGroups.filter((scheduleGroup:scheduleGroup)=>
scheduleGroup.id==scheduleGroupID);
};
}
@操作(GetScheduleGroups)
getscheduleGroups(patchState:StateContext<schedulesstatemodel>){
返回此.dataservice.getdocuments$<schedulegroup>('schedulegroups')
.pipe(tap(schedulegroups=>patchState(schedulegroups));
}
@操作(GetSchedules)
获取计划(patchState:StateContext<schedulesstatemodel>){
返回此.dataservice.getdocuments$<schedule>('schedules')
.pipe(tap(schedules=>patchstate(schedules));
}
< /代码>
在scheduleList组件中,我有以下代码:
getschedulesbyid$(schedulegroupid:string){
返回此.store.select(schedulesstate.schedulesByGroupID)
.pipe(映射(schedulesfilter=>schedulesfilter(schedulegroupid));
}
< /代码>
我可以将getschedulesbyid$的检索逻辑移到state类中,但是我现在对代码进行结构化的方式,需要一种为每个schedulegroup检索计划的方法;因为schedulegroup是迭代的,每个组的计划是检索来显示的。这可以在以下模板片段中看到:
<ngb选项卡
*ngfor=“让schedulegroup of(getschedulegroups$(schedulegroupcollection.id)async)”
[标题]=“scheduleGroup.name”>
<ng模板ngbtabcontent>
<div class=“schedules container”[ngStyle]=“height:tabheight”>
<IBMS计划列表项
*ngfor=“让调度(getschedules$(scheduleGroup.id)async)”
[schedule]=“时间表”>
</ibms计划列表项>
&L/DIV & GT;
</ng模板
</ngb选项卡>
< /代码>
这段代码可以工作,但看起来很冗长。有更好的方法吗?
我遇到的一个问题是,即使是简单的组件最终也会变成容器。以scheduleList组件为例,它需要显示相关表中的数据。获取此数据取决于在*ngfor迭代期间哪个特定计划项处于焦点。
有什么改进的建议吗?我几乎可以肯定有更好的方法,但我不确定它是什么。
另外,这里是数据服务:
import injectable from'@angular/core';
从'RXJS'导入可观察;
从“RXJS/内部兼容性”导入FromPromise;
从“rxjs/operators”导入map;
从“angularfire2/firestore”导入angularfirestore;
导入wherefilterop=firebase.firestore.wherefilterop;
从“guid typescript”导入guid;
可注射的({)
providedIn:'根'
})
导出类DataService{
建设者(私有数据库:angularfirestore)
getdocuments$<t>(collectionname:string):可观察的{
返回此.db.collection<t>(collectionname).snapshotchanges().pipe(
映射(actions=>actions.map(action=>){
const id=action.payload.doc.id;
const data:t=action.payload.doc.data()作为t;
数据['id']=id;
返回<t>数据;
})
;
}
GetDocumentsByQuery$<t>(集合名称:字符串,属性名称:字符串,
ComparisonOperator:WhereFilterOp,TargetValue:String_Boolean):可观察{
返回此.db.集合<t>。(
集合名
ref=>ref.where(propertyname、comparisonoperator、targetValue)).snapshotchanges().pipe(
映射(actions=>actions.map(action=>){
const id=action.payload.doc.id;
const data:t=action.payload.doc.data()作为t;
数据['id']=id;
返回数据;
})
;
}
adddocument<t>(集合名称:字符串,文档:t){
const-guid:string=guid.raw();
从Promise返回(this.db.collection<t>(collectionname).doc(guid).set(document)
管子(
图(())=gt;{
const返回文件:t=文件;
文档['id']=guid;
退货单;
})
;
}
addbatch<t>(集合名称:字符串,文档:数组<t>){
const batch=this.db.firestore.batch();
const collectionref=this.db.collection<t>(collectionname);
documents.foreach((document:t)=>。{
const-guid:string=guid.raw();
const doc ref=collectionref.doc(guid.ref);
批处理集(docref,document);
(});
从Promise返回(batch.commit());
}
updateDocument<t>(collectionName:string,document:t,data:any){
返回此.db.collection<t>(collectionname).doc(document['id']).update(data);
}
删除文档<t>(集合名称:字符串,文档:t){
返回此.db.collection<t>(collectionname).doc(document['id']).delete();
}
}
< /代码>
我知道这项服务可以改进,我会做好准备,但我认为为了完整起见,我会将其包括在内。
如有任何改进建议,我们将不胜感激。
以下是数据模型的一部分:
我已经将我的状态划分为功能模块,并有如下代码:
ngxsOnInit(ctx: StateContext<SchedulesStateModel>) {
ctx.dispatch([
new GetScheduleGroups(),
new GetSchedules()
]);
}
@Selector()
static scheduleGroups(state: SchedulesStateModel): Array<ScheduleGroup> {
return state.scheduleGroups;
}
@Selector()
static scheduleGroupById(state: SchedulesStateModel) {
return (scheduleGroupId: string) => {
return state.scheduleGroups.filter((scheduleGroup: ScheduleGroup) =>
scheduleGroup.id === scheduleGroupId);
};
}
@Action(GetScheduleGroups)
getScheduleGroups({ patchState }: StateContext<SchedulesStateModel>) {
return this.dataService.getDocuments$<ScheduleGroup>('scheduleGroups')
.pipe(tap(scheduleGroups => patchState({ scheduleGroups })));
}
@Action(GetSchedules)
getSchedules({ patchState }: StateContext<SchedulesStateModel>) {
return this.dataService.getDocuments$<Schedule>('schedules')
.pipe(tap(schedules => patchState({ schedules })));
}
在scheduleList组件中,我有以下代码:
getSchedulesById$(scheduleGroupId: string) {
return this.store.select(SchedulesState.schedulesByGroupId)
.pipe(map(schedulesFilter => schedulesFilter(scheduleGroupId)));
}
我可以将getschedulesbyid$的检索逻辑移到state类中,但是我现在对代码进行结构化的方式,需要一种为每个schedulegroup检索计划的方法;因为schedulegroup是迭代的,并且为显示而检索每个组的计划。这可以在以下模板片段中看到:
<ngb-tab
*ngFor="let scheduleGroup of (getScheduleGroups$(scheduleGroupCollection.id) | async)"
[title]="scheduleGroup.name">
<ng-template ngbTabContent>
<div class="schedules-container" [ngStyle]="{ height: tabHeight }">
<ibms-schedules-list-item
*ngFor="let schedule of (getSchedules$(scheduleGroup.id) | async)"
[schedule]="schedule">
</ibms-schedules-list-item>
</div>
</ng-template>
</ngb-tab>
这段代码可以工作,但看起来很冗长。有更好的方法吗?
我遇到的一个问题是,即使是简单的组件最终也会变成容器。以scheduleList组件为例,它需要显示相关表中的数据。获取此数据取决于在*ngfor迭代期间重点关注的特定计划项。
有什么改进的建议吗?我几乎可以肯定有更好的方法,但我不确定它是什么。
此外,这里还有数据服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { fromPromise } from 'rxjs/internal-compatibility';
import { map } from 'rxjs/operators';
import { AngularFirestore } from 'angularfire2/firestore';
import WhereFilterOp = firebase.firestore.WhereFilterOp;
import { Guid } from 'guid-typescript';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private db: AngularFirestore) {}
getDocuments$<T>(collectionName: string): Observable<T[]> {
return this.db.collection<T>(collectionName).snapshotChanges().pipe(
map(actions => actions.map(action => {
const id = action.payload.doc.id;
const data: T = action.payload.doc.data() as T;
data[ 'id' ] = id;
return <T>data;
}))
);
}
getDocumentsByQuery$<T>(collectionName: string, propertyName: string,
comparisonOperator: WhereFilterOp, targetValue: string | boolean): Observable<T[]> {
return this.db.collection<T>(
collectionName,
ref => ref.where(propertyName, comparisonOperator, targetValue)).snapshotChanges().pipe(
map(actions => actions.map(action => {
const id = action.payload.doc.id;
const data: T = action.payload.doc.data() as T;
data[ 'id' ] = id;
return data;
}))
);
}
addDocument<T>(collectionName: string, document: T) {
const guid: string = Guid.raw();
return fromPromise(this.db.collection<T>(collectionName).doc(guid).set(document))
.pipe(
map(() => {
const returnDocument: T = document;
document[ 'id' ] = guid;
return returnDocument;
})
);
}
addBatch<T>(collectionName: string, documents: Array<T>) {
const batch = this.db.firestore.batch();
const collectionRef = this.db.collection<T>(collectionName);
documents.forEach((document: T) => {
const guid: string = Guid.raw();
const docRef = collectionRef.doc(guid).ref;
batch.set(docRef, document);
});
return fromPromise(batch.commit());
}
updateDocument<T>(collectionName: string, document: T, data: any) {
return this.db.collection<T>(collectionName).doc(document['id']).update(data);
}
deleteDocument<T>(collectionName: string, document: T) {
return this.db.collection<T>(collectionName).doc(document['id']).delete();
}
}
我知道这个服务可以改进,我将着手做这件事,但我认为为了完整性,我会将它包括进来。
任何改进的建议都会受到赞赏。