Angular/angularfire2 - 读取可观察文档并将数据保存到对象。没有异步管道
Angular/angularfire2 - Read a document observable and save the data to an object. No async pipe
这个问题困扰我很久了,不知道怎么用我想要的方法解决。
基本上,我有一个名为 pages
的集合,其中包含所有页面文档。我有兴趣查询其中一个页面。我想阅读其中一份文档作为可观察对象,并使用 NgModel 指令实时更新数据。我想我已经弄清楚了那部分:我没有的是如何在不使用异步管道的情况下从 firebase 获取数据。
当我订阅数据流时,我没有得到数据对象(我可以立即使用的值),而是可观察的(然后我必须使用 HTML
中的异步管道来查看它)。有没有一种方法可以订阅数据并使用来自 firebase 的数据填充某些对象(基本上执行异步管道在组件 HTML 中执行的操作,但不使用异步管道?)。
下面是从 firebase 获取数据的 page.service.ts
逻辑:
/**
*
* @param workspaceId
* @param pageId
* GET A PAGE AS AN OBSERVABLE
* SNAPSHOT CHANGES ALLOWS THIS TO BE WRITTEN TO IN REAL TIME
*/
getWorkspacePage(workspaceId: string, pageId: string) {
return this.afAuth.authState.pipe(
map((user) => {
if (user) {
return this.fs.doc$(
`users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
);
} else {
return {};
}
})
);
}
下面是具体函数,doc$
:
/**
* GET THE DATA
*/
doc$<T>(ref: DocumentPredicate<T>): Observable<T> {
return this.doc(ref)
.snapshotChanges()
.pipe(
map((doc) => {
return doc.payload.data() as T;
})
);
}
这里是组件 ts
:
currentPage: Page;
@Input("currentPageId") currentPageId; // currentPageId
@Input() workspace; // workspaceId
sub: Subscription;
ngOnInit() {
// current page
this.sub = this.pageService
.getWorkspacePage(this.workspace.id, this.currentPageId)
.subscribe((pageData) => {
this.currentPage = pageData;
// now what must be done to get pageData as an object and not as an observable?
});
谢谢!
getWorkspacePage(workspaceId: string, pageId: string) {
return this.afAuth.authState.pipe(
map((user) => {
if (user) {
return this.fs.doc$(
`users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
);
} else {
return {};
}
})
);
}
在此方法中,使用了 map
,因此返回的 return this.fs.doc$ ...
是 Observable
而不是您想要的对象。
尝试像这样使用 switchMap
:
getWorkspacePage(workspaceId: string, pageId: string) {
return this.afAuth.authState.pipe(
switchMap((user) => {
if (user) {
return this.fs.doc$(
`users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
); // return page data as Observable
} else {
return of({}); // return a blank object as the Observable
}
})
);
}
这个问题困扰我很久了,不知道怎么用我想要的方法解决。
基本上,我有一个名为 pages
的集合,其中包含所有页面文档。我有兴趣查询其中一个页面。我想阅读其中一份文档作为可观察对象,并使用 NgModel 指令实时更新数据。我想我已经弄清楚了那部分:我没有的是如何在不使用异步管道的情况下从 firebase 获取数据。
当我订阅数据流时,我没有得到数据对象(我可以立即使用的值),而是可观察的(然后我必须使用 HTML
中的异步管道来查看它)。有没有一种方法可以订阅数据并使用来自 firebase 的数据填充某些对象(基本上执行异步管道在组件 HTML 中执行的操作,但不使用异步管道?)。
下面是从 firebase 获取数据的 page.service.ts
逻辑:
/**
*
* @param workspaceId
* @param pageId
* GET A PAGE AS AN OBSERVABLE
* SNAPSHOT CHANGES ALLOWS THIS TO BE WRITTEN TO IN REAL TIME
*/
getWorkspacePage(workspaceId: string, pageId: string) {
return this.afAuth.authState.pipe(
map((user) => {
if (user) {
return this.fs.doc$(
`users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
);
} else {
return {};
}
})
);
}
下面是具体函数,doc$
:
/**
* GET THE DATA
*/
doc$<T>(ref: DocumentPredicate<T>): Observable<T> {
return this.doc(ref)
.snapshotChanges()
.pipe(
map((doc) => {
return doc.payload.data() as T;
})
);
}
这里是组件 ts
:
currentPage: Page;
@Input("currentPageId") currentPageId; // currentPageId
@Input() workspace; // workspaceId
sub: Subscription;
ngOnInit() {
// current page
this.sub = this.pageService
.getWorkspacePage(this.workspace.id, this.currentPageId)
.subscribe((pageData) => {
this.currentPage = pageData;
// now what must be done to get pageData as an object and not as an observable?
});
谢谢!
getWorkspacePage(workspaceId: string, pageId: string) {
return this.afAuth.authState.pipe(
map((user) => {
if (user) {
return this.fs.doc$(
`users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
);
} else {
return {};
}
})
);
}
在此方法中,使用了 map
,因此返回的 return this.fs.doc$ ...
是 Observable
而不是您想要的对象。
尝试像这样使用 switchMap
:
getWorkspacePage(workspaceId: string, pageId: string) {
return this.afAuth.authState.pipe(
switchMap((user) => {
if (user) {
return this.fs.doc$(
`users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
); // return page data as Observable
} else {
return of({}); // return a blank object as the Observable
}
})
);
}