Angular Component 延遲載入 Lazy Load 的一個依賴注入的問題以及解決方案
阿新 • • 發佈:2021-07-22
StackOverflow上有個朋友遇到了一個問題:
在 feature module 裡,對一個 Component 進行延遲載入:
注意上圖第 9 行,匯入了 CommonModule.
這個被延遲載入的 Component 的模板檔案裡,使用到了 async 這個 pipe,其實現在 CommonModule 裡。然而,因為該 module 被延遲載入,因此並未靜態地定義在 feature module 的 declarations 模組裡。所以,該 Component 被載入的時候,其上下文無法訪問到 async pipe.
所以,最後會出現執行時錯誤:
ERROR Error: The pipe 'async' could not be found!
解決方案,我已經回覆在 StackOverflow 裡了:
在被延遲載入的 Component 裡,將其所屬的 feature module 的定義人工加上即可:
import { ChangeDetectionStrategy, Component, NgModule } from '@angular/core'; import { Product, provideDefaultConfig, CmsConfig } from '@spartacus/core'; import { CurrentProductService, MediaModule, OutletModule, CarouselModule } from '@spartacus/storefront'; import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs'; import { distinctUntilChanged, filter, map, tap } from 'rxjs/operators'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; @Component({ selector: 'app-product-images', templateUrl: './razer-product-images.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class CustomProductImagesComponent { private mainMediaContainer = new BehaviorSubject(null); private product$: Observable<Product> = this.currentProductService .getProduct() .pipe( filter(Boolean), distinctUntilChanged(), tap((p: Product) => { this.mainMediaContainer.next(p.images?.PRIMARY ? p.images.PRIMARY : {}); }) ); thumbs$: Observable<any[]> = this.product$.pipe( map((p: Product) => this.createThumbs(p)) ); mainImage$ = combineLatest([this.product$, this.mainMediaContainer]).pipe( map(([, container]) => container) ); constructor(private currentProductService: CurrentProductService) {} openImage(item: any): void { this.mainMediaContainer.next(item); } isActive(thumbnail): Observable<boolean> { return this.mainMediaContainer.pipe( filter(Boolean), map((container: any) => { return ( container.zoom && container.zoom.url && thumbnail.zoom && thumbnail.zoom.url && container.zoom.url === thumbnail.zoom.url ); }) ); } /** find the index of the main media in the list of media */ getActive(thumbs: any[]): Observable<number> { return this.mainMediaContainer.pipe( filter(Boolean), map((container: any) => { const current = thumbs.find( (t) => t.media && container.zoom && t.media.container && t.media.container.zoom && t.media.container.zoom.url === container.zoom.url ); return thumbs.indexOf(current); }) ); } /** * Return an array of CarouselItems for the product thumbnails. * In case there are less then 2 thumbs, we return null. */ private createThumbs(product: Product): Observable<any>[] { if ( !product.images || !product.images.GALLERY || product.images.GALLERY.length < 2 ) { return []; } return (<any[]>product.images.GALLERY).map((c) => of({ container: c })); } } @NgModule({ imports: [ CommonModule, RouterModule, MediaModule, OutletModule, CarouselModule ], declarations:[CustomProductImagesComponent] }) export class CustomProductImagesModule {}
更多Jerry的原創文章,盡在:"汪子熙":