我的目标是从 Firestore 获取数据并在服务器中渲染响应数据。
问题是,Firestore 以某种方式设法告诉组件不要等待,而只是将 HTML 发送到客户端。
如果我在 ngOnInit 中添加
setTimeout(() => {}, 1000)
,响应数据将在服务器中渲染。但是,显然,这是一种黑客行为,并且不能保证。
我正在使用 Angular 17。
@Component({
selector: 'app-experience',
standalone: true,
imports: [
NgIf,
AsyncPipe,
RouterLink,
],
templateUrl: './experience.page.html',
styleUrl: './experience.page.scss'
})
export class ExperiencePage implements OnInit {
documentId: Signal<string | null>;
slug: Signal<string | null>;
experience: Promise<Experience | null> = Promise.resolve(null);
constructor(
route: ActivatedRoute,
getExperience: GetExperienceUseCaseService,
private firestore: Firestore,
) {
const queryParamMap = route.queryParamMap;
// RxJs Interop
// see https://angular.io/guide/rxjs-interop
this.slug = toSignal(
queryParamMap.pipe(map((params) => params.get("slug"))),
{ initialValue: null }
);
this.documentId = toSignal(
queryParamMap.pipe(map((params) => params.get("documentId"))),
{ initialValue: null }
);
const collectionReference = collection(this.firestore, 'experiences');
const documentReference = doc(collectionReference, "CKfKFpCimmBxZpUJktud");
const documentSnapshot = getDoc(documentReference);
documentSnapshot.then((snapshot) => {
if (!snapshot.exists()) { return; }
const data = snapshot.data();
this.experience = Promise.resolve({
title: data["experienceTitle"],
type: data["experienceType"],
category: data["experienceCategory"],
rating: data["rating"],
});
})
}
ngOnInit() {
setTimeout(() => {
console.log("wait");
}, 1000)
}
}
尝试将代码移至ngOnInit,为什么它在
constructor
上?也许 SSR 等待 ngOnInit
完成而不是 constructor
?
@Component({
selector: 'app-experience',
standalone: true,
imports: [NgIf, AsyncPipe, RouterLink],
templateUrl: './experience.page.html',
styleUrl: './experience.page.scss',
})
export class ExperiencePage implements OnInit {
documentId: Signal<string | null>;
slug: Signal<string | null>;
experience: Promise<Experience | null> = Promise.resolve(null);
constructor(
route: ActivatedRoute,
getExperience: GetExperienceUseCaseService,
private firestore: Firestore
) {}
ngOnInit() {
const queryParamMap = this.route.queryParamMap;
// RxJs Interop
// see https://angular.io/guide/rxjs-interop
this.slug = toSignal(
queryParamMap.pipe(map((params) => params.get('slug'))),
{ initialValue: null }
);
this.documentId = toSignal(
queryParamMap.pipe(map((params) => params.get('documentId'))),
{ initialValue: null }
);
const collectionReference = collection(this.firestore, 'experiences');
const documentReference = doc(collectionReference, 'CKfKFpCimmBxZpUJktud');
const documentSnapshot = getDoc(documentReference);
documentSnapshot.then((snapshot) => {
if (!snapshot.exists()) {
return;
}
const data = snapshot.data();
this.experience = Promise.resolve({
title: data['experienceTitle'],
type: data['experienceType'],
category: data['experienceCategory'],
rating: data['rating'],
});
});
}
}