fix(ivy): execute the optional begin and end methods of the rendererFactory (#25273)
This is required to i.e. flush animations when using a Renderer2. `rf.begin()` and `rf.end()` around the change detection. PR Close #25273
This commit is contained in:
		
							parent
							
								
									0822dc70f2
								
							
						
					
					
						commit
						afa6b9e794
					
				| @ -96,14 +96,21 @@ export const CIRCULAR = '__CIRCULAR__'; | ||||
|  * Renderer2. | ||||
|  */ | ||||
| let renderer: Renderer3; | ||||
| let rendererFactory: RendererFactory3; | ||||
| let currentElementNode: LElementNode|null = null; | ||||
| 
 | ||||
| export function getRenderer(): Renderer3 { | ||||
|   // top level variables should not be exported for performance reasons (PERF_NOTES.md)
 | ||||
|   return renderer; | ||||
| } | ||||
| 
 | ||||
| let rendererFactory: RendererFactory3; | ||||
| 
 | ||||
| export function getRendererFactory(): RendererFactory3 { | ||||
|   // top level variables should not be exported for performance reasons (PERF_NOTES.md)
 | ||||
|   return rendererFactory; | ||||
| } | ||||
| 
 | ||||
| let currentElementNode: LElementNode|null = null; | ||||
| 
 | ||||
| export function getCurrentSanitizer(): Sanitizer|null { | ||||
|   return viewData && viewData[SANITIZER]; | ||||
| } | ||||
|  | ||||
| @ -11,11 +11,12 @@ import {ChangeDetectorRef as viewEngine_ChangeDetectorRef} from '../change_detec | ||||
| import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_container_ref'; | ||||
| import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, InternalViewRef as viewEngine_InternalViewRef} from '../linker/view_ref'; | ||||
| 
 | ||||
| import {checkNoChanges, checkNoChangesInRootView, detectChanges, detectChangesInRootView, markViewDirty, storeCleanupFn, viewAttached} from './instructions'; | ||||
| import {checkNoChanges, checkNoChangesInRootView, detectChanges, detectChangesInRootView, getRendererFactory, markViewDirty, storeCleanupFn, viewAttached} from './instructions'; | ||||
| import {LViewNode} from './interfaces/node'; | ||||
| import {FLAGS, LViewData, LViewFlags} from './interfaces/view'; | ||||
| import {destroyLView} from './node_manipulation'; | ||||
| 
 | ||||
| 
 | ||||
| // Needed due to tsickle downleveling where multiple `implements` with classes creates
 | ||||
| // multiple @extends in Closure annotations, which is illegal. This workaround fixes
 | ||||
| // the multiple @extends by making the annotation @implements instead
 | ||||
| @ -227,7 +228,16 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int | ||||
|    * | ||||
|    * See {@link ChangeDetectorRef#detach detach} for more information. | ||||
|    */ | ||||
|   detectChanges(): void { detectChanges(this.context); } | ||||
|   detectChanges(): void { | ||||
|     const rendererFactory = getRendererFactory(); | ||||
|     if (rendererFactory.begin) { | ||||
|       rendererFactory.begin(); | ||||
|     } | ||||
|     detectChanges(this.context); | ||||
|     if (rendererFactory.end) { | ||||
|       rendererFactory.end(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Checks the change detector and its children, and throws if any changes are detected. | ||||
|  | ||||
| @ -596,6 +596,9 @@ | ||||
|   { | ||||
|     "name": "getRenderer" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getRendererFactory" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getRootView" | ||||
|   }, | ||||
|  | ||||
| @ -8,11 +8,12 @@ | ||||
| 
 | ||||
| import {withBody} from '@angular/private/testing'; | ||||
| 
 | ||||
| import {ChangeDetectionStrategy, ChangeDetectorRef, DoCheck} from '../../src/core'; | ||||
| import {ChangeDetectionStrategy, ChangeDetectorRef, DoCheck, RendererType2} from '../../src/core'; | ||||
| import {getRenderedText, whenRendered} from '../../src/render3/component'; | ||||
| import {LifecycleHooksFeature, defineComponent, defineDirective, injectChangeDetectorRef} from '../../src/render3/index'; | ||||
| import {bind, container, containerRefreshEnd, containerRefreshStart, detectChanges, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation2, listener, markDirty, text, textBinding, tick} from '../../src/render3/instructions'; | ||||
| import {RenderFlags} from '../../src/render3/interfaces/definition'; | ||||
| import {RElement, Renderer3, RendererFactory3} from '../../src/render3/interfaces/renderer'; | ||||
| 
 | ||||
| import {containerEl, createComponent, renderComponent, requestAnimationFrame} from './render_util'; | ||||
| 
 | ||||
| @ -1043,4 +1044,40 @@ describe('change detection', () => { | ||||
| 
 | ||||
|   }); | ||||
| 
 | ||||
|   it('should call begin and end when the renderer factory implements them', () => { | ||||
|     const log: string[] = []; | ||||
| 
 | ||||
|     const testRendererFactory: RendererFactory3 = { | ||||
|       createRenderer: (hostElement: RElement | null, rendererType: RendererType2 | null): | ||||
|                           Renderer3 => { return document; }, | ||||
|       begin: () => log.push('begin'), | ||||
|       end: () => log.push('end'), | ||||
|     }; | ||||
| 
 | ||||
|     class MyComponent { | ||||
|       get value(): string { | ||||
|         log.push('detect changes'); | ||||
|         return 'works'; | ||||
|       } | ||||
| 
 | ||||
|       static ngComponentDef = defineComponent({ | ||||
|         type: MyComponent, | ||||
|         selectors: [['my-comp']], | ||||
|         factory: () => new MyComponent(), | ||||
|         template: (rf: RenderFlags, ctx: MyComponent) => { | ||||
|           if (rf & RenderFlags.Create) { | ||||
|             text(0); | ||||
|           } | ||||
|           if (rf & RenderFlags.Update) { | ||||
|             textBinding(0, bind(ctx.value)); | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     const myComp = renderComponent(MyComponent, {rendererFactory: testRendererFactory}); | ||||
|     expect(getRenderedText(myComp)).toEqual('works'); | ||||
|     expect(log).toEqual(['begin', 'detect changes', 'end']); | ||||
|   }); | ||||
| 
 | ||||
| }); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user