Skip to content

Commit

Permalink
refactor(component): use RenderScheduler as a service
Browse files Browse the repository at this point in the history
  • Loading branch information
markostanimirovic committed Jul 16, 2022
1 parent d0e544b commit 5aa2354
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 40 deletions.
31 changes: 29 additions & 2 deletions modules/component/spec/core/render-scheduler.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
import { createRenderScheduler } from '../../src/core/render-scheduler';
import {
createRenderScheduler,
RenderScheduler,
} from '../../src/core/render-scheduler';
import { NoopTickScheduler } from '../../src/core/tick-scheduler';
import { MockChangeDetectorRef } from '../fixtures/fixtures';
import { TestBed } from '@angular/core/testing';
import { ChangeDetectorRef, Injectable } from '@angular/core';

describe('createRenderScheduler', () => {
it('should initialize within injection context', () => {
@Injectable({ providedIn: 'root' })
class Service {
readonly renderScheduler = createRenderScheduler();
}

TestBed.configureTestingModule({
providers: [
{ provide: ChangeDetectorRef, useClass: MockChangeDetectorRef },
],
});

const renderScheduler = TestBed.inject(Service).renderScheduler;
expect(renderScheduler).toBeDefined();
});

it('should throw an error out of injection context', () => {
expect(() => createRenderScheduler()).toThrow();
});
});

describe('RenderScheduler', () => {
function setup() {
const cdRef = new MockChangeDetectorRef();
const tickScheduler = new NoopTickScheduler();
jest.spyOn(tickScheduler, 'schedule');
const renderScheduler = createRenderScheduler({ cdRef, tickScheduler });
const renderScheduler = new RenderScheduler(cdRef, tickScheduler);

return { cdRef, renderScheduler, tickScheduler };
}
Expand Down
2 changes: 1 addition & 1 deletion modules/component/spec/types/push.pipe.types.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('PushPipe', () => {
import { PushPipe } from '@ngrx/component';
const anyVal = {} as any;
const pushPipe = new PushPipe(anyVal, anyVal, anyVal);
const pushPipe = new PushPipe(anyVal, anyVal);
const value = pushPipe.transform(anyVal as ${potentialObservableType});
`
);
Expand Down
29 changes: 13 additions & 16 deletions modules/component/src/core/render-scheduler.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import { ChangeDetectorRef } from '@angular/core';
import { ChangeDetectorRef, inject, Injectable } from '@angular/core';
import { TickScheduler } from './tick-scheduler';

export interface RenderScheduler {
schedule(): void;
}

export interface RenderSchedulerConfig {
cdRef: ChangeDetectorRef;
tickScheduler: TickScheduler;
}
@Injectable()
export class RenderScheduler {
constructor(
private cdRef: ChangeDetectorRef,
private tickScheduler: TickScheduler
) {}

export function createRenderScheduler(
config: RenderSchedulerConfig
): RenderScheduler {
function schedule(): void {
config.cdRef.markForCheck();
config.tickScheduler.schedule();
schedule(): void {
this.cdRef.markForCheck();
this.tickScheduler.schedule();
}
}

return { schedule };
export function createRenderScheduler(): RenderScheduler {
return new RenderScheduler(inject(ChangeDetectorRef), inject(TickScheduler));
}
22 changes: 11 additions & 11 deletions modules/component/src/let/let.directive.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
ChangeDetectorRef,
Directive,
ErrorHandler,
Host,
Input,
OnDestroy,
OnInit,
Optional,
TemplateRef,
ViewContainerRef,
} from '@angular/core';
Expand All @@ -13,9 +14,11 @@ import {
ObservableOrPromise,
PotentialObservable,
} from '../core/potential-observable';
import { createRenderScheduler } from '../core/render-scheduler';
import {
createRenderScheduler,
RenderScheduler,
} from '../core/render-scheduler';
import { createRenderEventManager } from '../core/render-event/manager';
import { TickScheduler } from '../core/tick-scheduler';

type LetViewContextValue<PO> = PO extends ObservableOrPromise<infer V> ? V : PO;

Expand Down Expand Up @@ -114,10 +117,6 @@ export class LetDirective<PO> implements OnInit, OnDestroy {
$complete: false,
$suspense: true,
};
private readonly renderScheduler = createRenderScheduler({
cdRef: this.cdRef,
tickScheduler: this.tickScheduler,
});
private readonly renderEventManager = createRenderEventManager<
LetViewContextValue<PO>
>({
Expand Down Expand Up @@ -182,12 +181,13 @@ export class LetDirective<PO> implements OnInit, OnDestroy {
>;

constructor(
private readonly cdRef: ChangeDetectorRef,
private readonly tickScheduler: TickScheduler,
private readonly mainTemplateRef: TemplateRef<LetViewContext<PO>>,
private readonly viewContainerRef: ViewContainerRef,
private readonly errorHandler: ErrorHandler
) {}
private readonly errorHandler: ErrorHandler,
@Optional() @Host() private readonly renderScheduler: RenderScheduler
) {
this.renderScheduler ??= createRenderScheduler();
}

static ngTemplateContextGuard<PO>(
dir: LetDirective<PO>,
Expand Down
20 changes: 10 additions & 10 deletions modules/component/src/push/push.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import {
ChangeDetectorRef,
ErrorHandler,
Host,
OnDestroy,
Optional,
Pipe,
PipeTransform,
} from '@angular/core';
import { Unsubscribable } from 'rxjs';
import { ObservableOrPromise } from '../core/potential-observable';
import { createRenderScheduler } from '../core/render-scheduler';
import {
createRenderScheduler,
RenderScheduler,
} from '../core/render-scheduler';
import { createRenderEventManager } from '../core/render-event/manager';
import { TickScheduler } from '../core/tick-scheduler';

type PushPipeResult<PO> = PO extends ObservableOrPromise<infer R>
? R | undefined
Expand Down Expand Up @@ -39,10 +42,6 @@ type PushPipeResult<PO> = PO extends ObservableOrPromise<infer R>
@Pipe({ name: 'ngrxPush', pure: false })
export class PushPipe implements PipeTransform, OnDestroy {
private renderedValue: unknown;
private readonly renderScheduler = createRenderScheduler({
cdRef: this.cdRef,
tickScheduler: this.tickScheduler,
});
private readonly renderEventManager = createRenderEventManager({
suspense: () => this.setRenderedValue(undefined),
next: (event) => this.setRenderedValue(event.value),
Expand All @@ -61,10 +60,11 @@ export class PushPipe implements PipeTransform, OnDestroy {
private readonly subscription: Unsubscribable;

constructor(
private readonly cdRef: ChangeDetectorRef,
private readonly tickScheduler: TickScheduler,
private readonly errorHandler: ErrorHandler
private readonly errorHandler: ErrorHandler,
@Optional() @Host() private readonly renderScheduler: RenderScheduler
) {
this.renderScheduler ??= createRenderScheduler();

this.subscription = this.renderEventManager
.handlePotentialObservableChanges()
.subscribe();
Expand Down

0 comments on commit 5aa2354

Please sign in to comment.