我的 Angular 客户端应用程序中有两个不相关的组件。第一个组件负责从服务器获取和处理数据。我正在尝试使用订阅回调函数导航到新页面并显示已处理的数据(blob)。更具体地说,我想转到一个新选项卡并使用不相关的组件预览 Word 文档。我发现可以使用具有 RxJS 主题的服务通过不相关的组件传递数据。
我已经实现了一些代码,但我的博客没有到达预览组件。
这是我想出的一些代码:
传输 Blob 对象的服务
@Injectable()
export class DocPreviewService {
private blob = new BehaviorSubject<Blob | undefined>(undefined);
public share$ = this.blob.asObservable();
constructor() {}
setBlob(blob: Blob) {
this.blob.next(blob);
}
}
负责从服务器检索 blob 的函数(第一个组件)
showReport(selected_id: string) {
const url = this.router.serializeUrl(this.router.createUrlTree([`tools/${selected_id}/preview`]));
// it's important that the page opens in a new tab
window.open(url, '_blank');
this.report_service.createReport(this.calc_items[selected_id]).subscribe({
next: (doc_blob: Blob) => {
{
this.doc_preview_service.setBlob(doc_blob);
}
},
error: (error: any) => {
},
})
}
负责查看文档的组件(第二个组件)
export class DocPreviewComponent implements OnChanges, AfterViewInit, OnDestroy {
doc_blob?: Blob;
@ViewChild('doc_preview') doc_preview!: ElementRef;
subscription: Subscription;
constructor(private doc_preview_service: DocPreviewService, private local_storage: LocalStorageService) {
this.subscription = this.doc_preview_service.share$.subscribe(blob => {
this.doc_blob = blob;
});
}
ngOnChanges(changes: SimpleChanges): void {}
ngAfterViewInit(): void {
if (this.doc_blob) {
doc.renderAsync(this.doc_blob, this.doc_preview.nativeElement)
.then(x => console.log("docx: finished"));
}
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
任何帮助将不胜感激。谢谢你。
实际上,主题发射器方法有一个限制,它仅适用于单个选项卡中不相关组件之间的通信,不可能进行跨选项卡通信,因为该服务在每个选项卡中将有两个单独的实例,因此永远不会收到事件
要解决这种情况,您只需将 API 调用参数附加到 URL 即可
打开选项卡的代码
showReport(selected_id: string) {
// basically we append the required param needed for making the API
// call, then we use it to call the blob logic on the other tab initialization!
const url = this.router.serializeUrl(this.router.createUrlTree([`tools/${selected_id}/preview?id=${this.calc_items[selected_id]}`]));
// it's important that the page opens in a new tab
window.open(url, '_blank');
}
打开 blob 的组件将是
export class DocPreviewComponent implements OnChanges, AfterViewInit, OnDestroy {
doc_blob?: Blob;
@ViewChild('doc_preview') doc_preview!: ElementRef;
subscription: Subscription;
constructor(private doc_preview_service: DocPreviewService, private local_storage: LocalStorageService) { }
ngOnChanges(changes: SimpleChanges): void {}
ngAfterViewInit(): void {
this.report_service.createReport(this.activatedRoute.snapshot.queryParams.id).subscribe({
next: (doc_blob: Blob) => {
this.doc_blob = doc_blob;
if (this.doc_blob) {
doc.renderAsync(this.doc_blob, this.doc_preview.nativeElement)
.then(x => console.log("docx: finished"));
}
},
error: (error: any) => {},
})
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}