Skip to content

Instantly share code, notes, and snippets.

@NyaGarcia
Created May 1, 2020 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NyaGarcia/4aa6951c73fb9b0943e6cb0a192a3a28 to your computer and use it in GitHub Desktop.
Save NyaGarcia/4aa6951c73fb9b0943e6cb0a192a3a28 to your computer and use it in GitHub Desktop.
Creando una directiva personalizada para renderizar Observables en el template
import {
Directive, Input, TemplateRef, ViewContainerRef,
OnDestroy, OnInit, ChangeDetectorRef
} from '@angular/core'
import { Observable, Subject, AsyncSubject } from "rxjs";
import { takeUntil, concatMapTo } from "rxjs/operators";
export interface ObserveContext<T> {
$implicit: T;
observe: T;
}
export interface ErrorContext {
$implicit: Error;
}
@Directive({
selector: "[observe]"
})
export class ObserveDirective<T> implements OnDestroy, OnInit {
private errorRef: TemplateRef<ErrorContext>;
private beforeRef: TemplateRef<null>;
private unsubscribe = new Subject<boolean>();
private init = new AsyncSubject<void>();
constructor(
private view: ViewContainerRef,
private nextRef: TemplateRef<ObserveContext<T>>,
private changes: ChangeDetectorRef
) {}
@Input()
set observe(source: Observable<T>) {
if (!source) {
return
}
this.showBefore()
this.unsubscribe.next(true);
this.init.pipe(
concatMapTo(source),
takeUntil(this.unsubscribe)
).subscribe(value => {
this.view.clear()
this.view.createEmbeddedView(this.nextRef, {$implicit: value, observe: value})
this.changes.markForCheck()
}, error => {
if (this.errorRef) {
this.view.clear()
this.view.createEmbeddedView(this.errorRef, {$implicit: error})
this.changes.markForCheck()
}
})
}
@Input()
set observeError(ref: TemplateRef<ErrorContext>) {
this.errorRef = ref;
}
@Input()
set observeBefore(ref: TemplateRef<null>) {
this.beforeRef = ref;
}
ngOnDestroy() {
this.unsubscribe.next(true)
}
ngOnInit() {
this.showBefore()
this.init.next()
this.init.complete()
}
private showBefore(): void {
if (this.beforeRef) {
this.view.clear()
this.view.createEmbeddedView(this.beforeRef)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment