【发布时间】:2019-03-21 14:25:52
【问题描述】:
我有以下提供程序工厂,用于动态计算的 firebase firestore 路径:
const meetingServiceFactory = (db: AngularFirestore, authService: AuthService ) => {
const userId = authService.user;
return new MeetingService('/users/' + userId + '/meetings', db);
};
export let meetingServiceProvider = { provide: MeetingService,
useFactory: meetingServiceFactory,
deps: [AngularFirestore, AuthService] };
这里是MeetingService:
@Injectable(
{
providedIn: 'root'
}
)
export class MeetingService extends FirestoreDataService<Meeting> {
constructor(path: string, db: AngularFirestore) {
super(path, db);
}
setProposalFlag(meetingKey: string) {
return from(this.db.doc(this.path + `/${meetingKey}`).update({hasProposal: true})
.then(result => console.log('changed active Flag on meeting: ', result))
.catch(err => console.log(err)));
}
saveMeeting(meeting: Meeting) {
return of(meeting).pipe(
map(meetingToSave => {
return {...meetingToSave, key: this.db.createId() };
}),
switchMap( finalMeeting => this.addItemWithKey(finalMeeting.key, finalMeeting) )
);
}
getAll() {
return this.getItems();
}
}
这继承自 FirestoreDataService<T>,所以我有一种 CRUD 服务可以重用:
@Injectable()
export class FirestoreDataService<T> {
protected itemCollection: AngularFirestoreCollection<T>;
protected items$: Observable<T[]>;
protected snapshot$: Observable<DocumentChangeAction<T>[]>;
protected state$: Observable<DocumentChangeAction<T>[]>;
constructor(protected path: string, protected db: AngularFirestore) {
this.itemCollection = this.db.collection<T>(path);
this.items$ = this.itemCollection.valueChanges();
this.snapshot$ = this.itemCollection.snapshotChanges();
this.state$ = this.itemCollection.stateChanges();
}
getItems(): Observable<T[]> {
return this.items$;
}
getItemWithKey( key: string): Observable<T> {
// used to use stateChanges here.
// as the doc states, this only emits recent changes,
// so if we subscribe in an async pipe, it will not reemit and subsequent observables will be empty.
return this.itemCollection.doc<T>(key).valueChanges();
}
addItem(data: T) {
return from(this.itemCollection.add(data)
.catch(err => console.log('Error while adding item: ', err)));
}
addItemWithKey(key: string, data: T) {
return from(this.itemCollection.doc(key).set(data)
.catch(err => console.log('Error while adding item: ', err)));
}
deleteItem(key: string) {
return from(this.itemCollection.doc(key).delete()
.catch(err => console.log('Error while deleting item: ', err)));
}
}
,但它显然取决于 userId 的运行时决策。似乎在 ng serve 内工作正常,但在为 prod 编译时,我得到:ERROR in : Can't resolve all parameters for FirestoreDataService in /web-client/src/app/core/services/firestore-data.service.ts: (?, [object Object]).
我认为这是因为我在编译时不知道确切的路径。是这样吗?如果没有,这个设置可能有什么问题?我将如何修复它/改进它?我现在运行 Angular 7。感谢您的帮助!
【问题讨论】:
-
您是否尝试从
FirestoreDataService中删除@Injectable()装饰器?因为无论如何你都是自己实例化类实例,没有 Angular DI。 -
@BorysKupar。是的,试过了。没用。
-
这种情况下显示的错误是一样的吗?
-
你如何使用
meetingServiceProvider? -
@BorysKupar 是的,同样的错误。我将它注入到我的模块中:
providers: [ FormBuilder, MeetingForm, meetingServiceProvider, GeocodingService ]
标签: angular typescript firebase dependency-injection angular7