( viewContainerRef: ViewContainerRef )
| 48 | * |
| 49 | */ |
| 50 | export function templateHandling<N, C>( |
| 51 | viewContainerRef: ViewContainerRef |
| 52 | ): { |
| 53 | add(name: N, templateRef: TemplateRef<C>): void; |
| 54 | get(name: N): TemplateRef<C>; |
| 55 | get$(name: N): Observable<TemplateRef<C>>; |
| 56 | createEmbeddedView(name: N, context?: C, index?: number): EmbeddedViewRef<C>; |
| 57 | } { |
| 58 | const templateCache = new Map<N, Subject<TemplateRef<C>>>(); |
| 59 | |
| 60 | const get$ = (name: N): Observable<TemplateRef<C>> => { |
| 61 | return templateCache.get(name) || of(undefined); |
| 62 | }; |
| 63 | const get = (name: N): TemplateRef<C> | undefined => { |
| 64 | let ref: TemplateRef<C>; |
| 65 | const templatRef$ = get$(name); |
| 66 | if (templatRef$) { |
| 67 | const sub = templatRef$.subscribe((r) => (ref = r)); |
| 68 | sub.unsubscribe(); |
| 69 | } |
| 70 | return ref; |
| 71 | }; |
| 72 | |
| 73 | return { |
| 74 | add(name: N, templateRef: TemplateRef<C>): void { |
| 75 | assertTemplate(name, templateRef); |
| 76 | if (!templateCache.has(name)) { |
| 77 | templateCache.set( |
| 78 | name, |
| 79 | new BehaviorSubject<TemplateRef<C>>(templateRef) |
| 80 | ); |
| 81 | } else { |
| 82 | templateCache.get(name).next(templateRef); |
| 83 | } |
| 84 | }, |
| 85 | get$, |
| 86 | get, |
| 87 | createEmbeddedView: (name: N, context?: C) => |
| 88 | createEmbeddedView(viewContainerRef, get(name), context), |
| 89 | }; |
| 90 | |
| 91 | // |
| 92 | function assertTemplate<T>( |
| 93 | property: any, |
| 94 | templateRef: TemplateRef<T> | null |
| 95 | ): templateRef is TemplateRef<T> { |
| 96 | const isTemplateRefOrNull = !!( |
| 97 | !templateRef || templateRef.createEmbeddedView |
| 98 | ); |
| 99 | if (!isTemplateRefOrNull) { |
| 100 | throw new Error( |
| 101 | `${property} must be a TemplateRef, but received ${typeof templateRef}` |
| 102 | ); |
| 103 | } |
| 104 | return isTemplateRefOrNull; |
| 105 | } |
| 106 | } |
| 107 |
no test coverage detected