Skip to content

Instantly share code, notes, and snippets.

@waterplea
Created September 8, 2020 17:56
Show Gist options
  • Save waterplea/d9f226524cfbff89cf01753d2515c15c to your computer and use it in GitHub Desktop.
Save waterplea/d9f226524cfbff89cf01753d2515c15c to your computer and use it in GitHub Desktop.
ngFor for maps with delay on removal
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(() => {
value.destroy();
}, 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