Created
August 13, 2020 07:37
-
-
Save waterplea/7a23a87b657804a0c7eb7456b1049cd5 to your computer and use it in GitHub Desktop.
ngFor for immutable maps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class ForMapOfContext<T> { | |
destroyed = false; | |
constructor(readonly $implicit: T) {} | |
} | |
@Directive({selector: '[ngForMap][ngForMapOf]'}) | |
export class ForMapOfDirective<T, G> { | |
@Input() | |
set ngForMapOf(map: Map<T, G>) { | |
for (const key of this.map.keys()) { | |
if (!map.has(key)) { | |
const value = this.map.get(key)!; | |
value.context.destroyed = true; | |
this.map.delete(key); | |
setTimeout(() => { | |
this.viewContainerRef.remove(this.viewContainerRef.indexOf(value)); | |
}, this.release); | |
} | |
} | |
for (const key of map.keys()) { | |
if (!this.map.has(key)) { | |
this.map.set( | |
key, | |
this.viewContainerRef.createEmbeddedView( | |
this.template, | |
new ForMapOfContext(key), | |
), | |
); | |
} | |
} | |
} | |
@Input() | |
release = 1000; | |
private readonly map: Map<T, EmbeddedViewRef<ForMapOfContext<T>>> = new Map(); | |
constructor( | |
@Inject(ViewContainerRef) | |
private readonly viewContainerRef: ViewContainerRef, | |
@Inject(TemplateRef) | |
private readonly template: TemplateRef<ForMapOfContext<T>>, | |
) {} | |
static ngTemplateContextGuard<T, G>( | |
_dir: ForMapOfDirective<T, G>, | |
_ctx: unknown, | |
): _ctx is ForMapOfContext<T> { | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment