Skip to content

Commit

Permalink
fix: 🐛 run change detection only on the embeded view
Browse files Browse the repository at this point in the history
  • Loading branch information
shaharkazaz committed Jan 30, 2022
1 parent 462f31d commit 18b2a3b
Showing 1 changed file with 19 additions and 13 deletions.
32 changes: 19 additions & 13 deletions projects/ngneat/subscribe/src/lib/subscribe.directive.ts
Expand Up @@ -7,6 +7,7 @@ import {
ViewContainerRef,
NgModule,
OnDestroy,
EmbeddedViewRef,
} from '@angular/core';
import { Observable, Subscription } from 'rxjs';
interface SubscribeContext<T> {
Expand All @@ -16,19 +17,20 @@ interface SubscribeContext<T> {
completed: boolean;
}

type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N;
type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;

@Directive({
selector: '[subscribe]',
})
export class SubscribeDirective<T, InitialSyncValue extends boolean = true> implements OnInit, OnDestroy {
private subscription: Subscription | null = null;
private viewRef: EmbeddedViewRef<any> | null = null;

private context: SubscribeContext<any> = {
$implicit: undefined,
subscribe: undefined,
error: undefined,
completed: false
completed: false,
};

@Input() initialSyncValue!: InitialSyncValue;
Expand All @@ -45,40 +47,44 @@ export class SubscribeDirective<T, InitialSyncValue extends boolean = true> impl
next: (value) => {
this.context.$implicit = value;
this.context.subscribe = value;

this.cdr[this.strategy]();
this.onChange();
},
error: (err) => {
this.context.error = err;
this.cdr[this.strategy]();
this.onChange();
},
complete: () => {
this.context.completed = true;
this.cdr[this.strategy]();
this.onChange();
},
});
}

static ngTemplateContextGuard<T, InitialSyncValue extends boolean = true>(
directive: SubscribeDirective<T, InitialSyncValue>,
context: unknown
): context is SubscribeContext<IfAny<InitialSyncValue, T, T | undefined>>{
): context is SubscribeContext<IfAny<InitialSyncValue, T, T | undefined>> {
return true;
}

constructor(
private tpl: TemplateRef<any>,
private cdr: ChangeDetectorRef,
private vcr: ViewContainerRef
) {}
constructor(private tpl: TemplateRef<any>, private cdr: ChangeDetectorRef, private vcr: ViewContainerRef) {}

ngOnInit() {
this.vcr.createEmbeddedView(this.tpl, this.context);
this.viewRef = this.vcr.createEmbeddedView(this.tpl, this.context);
}

ngOnDestroy() {
this.subscription?.unsubscribe();
this.subscription = null;
this.viewRef = null;
}

private onChange() {
if (this.strategy === 'markForCheck') {
this.cdr.markForCheck();
} else {
this.viewRef?.detectChanges();
}
}
}

Expand Down

0 comments on commit 18b2a3b

Please sign in to comment.