diff --git a/packages/core/src/render/api.ts b/packages/core/src/render/api.ts index f0f02e9e65..630de09f81 100644 --- a/packages/core/src/render/api.ts +++ b/packages/core/src/render/api.ts @@ -127,6 +127,8 @@ export interface RendererType2 { */ export abstract class RendererFactory2 { abstract createRenderer(hostElement: any, type: RendererType2|null): Renderer2; + abstract begin?(): void; + abstract end?(): void; } /** diff --git a/packages/core/src/view/refs.ts b/packages/core/src/view/refs.ts index fac2adef91..5c5ff5368f 100644 --- a/packages/core/src/view/refs.ts +++ b/packages/core/src/view/refs.ts @@ -239,7 +239,16 @@ export class ViewRef_ implements EmbeddedViewRef, InternalViewRef { markForCheck(): void { markParentViewsForCheck(this._view); } detach(): void { this._view.state &= ~ViewState.Attached; } - detectChanges(): void { Services.checkAndUpdateView(this._view); } + detectChanges(): void { + const fs = this._view.root.rendererFactory; + if (fs.begin) { + fs.begin(); + } + Services.checkAndUpdateView(this._view); + if (fs.end) { + fs.end(); + } + } checkNoChanges(): void { Services.checkNoChangesView(this._view); } reattach(): void { this._view.state |= ViewState.Attached; } diff --git a/packages/core/src/view/services.ts b/packages/core/src/view/services.ts index edfa53b357..d7aa1bf716 100644 --- a/packages/core/src/view/services.ts +++ b/packages/core/src/view/services.ts @@ -456,6 +456,17 @@ class DebugRendererFactory2 implements RendererFactory2 { createRenderer(element: any, renderData: RendererType2|null): Renderer2 { return new DebugRenderer2(this.delegate.createRenderer(element, renderData)); } + + begin() { + if (this.delegate.begin) { + this.delegate.begin(); + } + } + end() { + if (this.delegate.end) { + this.delegate.end(); + } + } } diff --git a/packages/core/test/linker/change_detection_integration_spec.ts b/packages/core/test/linker/change_detection_integration_spec.ts index 3df8f8df53..34a9afff00 100644 --- a/packages/core/test/linker/change_detection_integration_spec.ts +++ b/packages/core/test/linker/change_detection_integration_spec.ts @@ -666,6 +666,22 @@ export function main() { }); + describe('RendererFactory', () => { + it('should call the begin and end methods on the renderer factory when change detection is called', + fakeAsync(() => { + const ctx = createCompFixture('
'); + const rf = TestBed.get(RendererFactory2); + spyOn(rf, 'begin'); + spyOn(rf, 'end'); + expect(rf.begin).not.toHaveBeenCalled(); + expect(rf.end).not.toHaveBeenCalled(); + + ctx.detectChanges(false); + expect(rf.begin).toHaveBeenCalled(); + expect(rf.end).toHaveBeenCalled(); + })); + }); + describe('change notification', () => { describe('updating directives', () => { it('should happen without invoking the renderer', fakeAsync(() => { diff --git a/packages/platform-browser/animations/src/animation_renderer.ts b/packages/platform-browser/animations/src/animation_renderer.ts index 5f06125e4a..36d762e1a9 100644 --- a/packages/platform-browser/animations/src/animation_renderer.ts +++ b/packages/platform-browser/animations/src/animation_renderer.ts @@ -25,6 +25,17 @@ export class AnimationRendererFactory implements RendererFactory2 { trigger => this._engine.registerTrigger(trigger, namespaceify(namespaceId, trigger.name))); return new AnimationRenderer(delegate, this._engine, this._zone, namespaceId); } + + begin() { + if (this.delegate.begin) { + this.delegate.begin(); + } + } + end() { + if (this.delegate.end) { + this.delegate.end(); + } + } } export class AnimationRenderer implements Renderer2 { diff --git a/packages/platform-browser/src/dom/dom_renderer.ts b/packages/platform-browser/src/dom/dom_renderer.ts index 0ed6c793cf..221b994070 100644 --- a/packages/platform-browser/src/dom/dom_renderer.ts +++ b/packages/platform-browser/src/dom/dom_renderer.ts @@ -94,6 +94,9 @@ export class DomRendererFactory2 implements RendererFactory2 { } } } + + begin() {} + end() {} } class DefaultDomRenderer2 implements Renderer2 { diff --git a/packages/platform-server/src/server_renderer.ts b/packages/platform-server/src/server_renderer.ts index 3984946f6d..1fed05cd98 100644 --- a/packages/platform-server/src/server_renderer.ts +++ b/packages/platform-server/src/server_renderer.ts @@ -52,6 +52,9 @@ export class ServerRendererFactory2 implements RendererFactory2 { } } } + + begin() {} + end() {} } class DefaultServerRenderer2 implements Renderer2 { diff --git a/packages/platform-webworker/src/web_workers/worker/renderer.ts b/packages/platform-webworker/src/web_workers/worker/renderer.ts index 4d8db95df1..a70c0eb4cf 100644 --- a/packages/platform-webworker/src/web_workers/worker/renderer.ts +++ b/packages/platform-webworker/src/web_workers/worker/renderer.ts @@ -81,6 +81,9 @@ export class WebWorkerRendererFactory2 implements RendererFactory2 { return renderer; } + begin() {} + end() {} + callUI(fnName: string, fnArgs: FnArg[]) { const args = new UiArguments(fnName, fnArgs); this._messageBroker.runOnService(args, null); diff --git a/tools/public_api_guard/core/core.d.ts b/tools/public_api_guard/core/core.d.ts index 56471d2bb2..707e591e9d 100644 --- a/tools/public_api_guard/core/core.d.ts +++ b/tools/public_api_guard/core/core.d.ts @@ -846,7 +846,9 @@ export declare abstract class Renderer2 { /** @experimental */ export declare abstract class RendererFactory2 { + abstract begin?(): void; abstract createRenderer(hostElement: any, type: RendererType2 | null): Renderer2; + abstract end?(): void; } /** @experimental */