fix(ivy): ensure renderer begin/end methods are only called during change detection (#28192)
In VE the renderer.begin() and renderer.end() methods are only called when CD is called on an element. This patch ensures that Ivy does the same thing. Jira issue: FW-945 PR Close #28192
This commit is contained in:
		
							parent
							
								
									1f7d3b9a57
								
							
						
					
					
						commit
						896cf35afb
					
				| @ -169,8 +169,6 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> { | ||||
|     let component: T; | ||||
|     let tElementNode: TElementNode; | ||||
|     try { | ||||
|       if (rendererFactory.begin) rendererFactory.begin(); | ||||
| 
 | ||||
|       const componentView = createRootComponentView( | ||||
|           hostRNode, this.componentDef, rootLView, rendererFactory, renderer); | ||||
| 
 | ||||
| @ -216,7 +214,6 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> { | ||||
|       refreshDescendantViews(rootLView); | ||||
|     } finally { | ||||
|       leaveView(oldLView); | ||||
|       if (rendererFactory.end) rendererFactory.end(); | ||||
|     } | ||||
| 
 | ||||
|     const componentRef = new ComponentRef( | ||||
|  | ||||
| @ -395,12 +395,13 @@ function renderComponentOrTemplate<T>( | ||||
|   const rendererFactory = hostView[RENDERER_FACTORY]; | ||||
|   const oldView = enterView(hostView, hostView[HOST_NODE]); | ||||
|   const normalExecutionPath = !getCheckNoChangesMode(); | ||||
|   const creationModeIsActive = isCreationMode(hostView); | ||||
|   try { | ||||
|     if (normalExecutionPath && rendererFactory.begin) { | ||||
|     if (normalExecutionPath && !creationModeIsActive && rendererFactory.begin) { | ||||
|       rendererFactory.begin(); | ||||
|     } | ||||
| 
 | ||||
|     if (isCreationMode(hostView)) { | ||||
|     if (creationModeIsActive) { | ||||
|       // creation mode pass
 | ||||
|       if (templateFn) { | ||||
|         namespaceHTML(); | ||||
| @ -415,7 +416,7 @@ function renderComponentOrTemplate<T>( | ||||
|     templateFn && templateFn(RenderFlags.Update, context !); | ||||
|     refreshDescendantViews(hostView); | ||||
|   } finally { | ||||
|     if (normalExecutionPath && rendererFactory.end) { | ||||
|     if (normalExecutionPath && !creationModeIsActive && rendererFactory.end) { | ||||
|       rendererFactory.end(); | ||||
|     } | ||||
|     leaveView(oldView); | ||||
|  | ||||
| @ -803,58 +803,56 @@ import {HostListener} from '../../src/metadata/directives'; | ||||
|         expect(player.element.style.height).toEqual('444px'); | ||||
|       }); | ||||
| 
 | ||||
|       fixmeIvy( | ||||
|           'FW-945 - Ivy createComponent calls CD while VE waits for CD to be explicitly called') | ||||
|           .it('should find newly inserted items in the component via :enter', () => { | ||||
|             @Component({ | ||||
|               selector: 'ani-cmp', | ||||
|               template: ` | ||||
|       it('should find newly inserted items in the component via :enter', () => { | ||||
|         @Component({ | ||||
|           selector: 'ani-cmp', | ||||
|           template: ` | ||||
|             <div @myAnimation> | ||||
|               <div *ngFor="let item of items" class="child"> | ||||
|                 {{ item }} | ||||
|               </div> | ||||
|             </div> | ||||
|           `,
 | ||||
|               animations: [trigger( | ||||
|                   'myAnimation', | ||||
|                   [ | ||||
|                     transition( | ||||
|                         ':enter', | ||||
|                         [ | ||||
|                           query( | ||||
|                               ':enter', | ||||
|                               [ | ||||
|                                 style({opacity: 0}), | ||||
|                                 animate(1000, style({opacity: .5})), | ||||
|                               ]), | ||||
|                         ]), | ||||
|                   ])] | ||||
|             }) | ||||
|             class Cmp { | ||||
|               public items: any[] = [0, 1, 2]; | ||||
|             } | ||||
|           animations: [trigger( | ||||
|               'myAnimation', | ||||
|               [ | ||||
|                 transition( | ||||
|                     ':enter', | ||||
|                     [ | ||||
|                       query( | ||||
|                           ':enter', | ||||
|                           [ | ||||
|                             style({opacity: 0}), | ||||
|                             animate(1000, style({opacity: .5})), | ||||
|                           ]), | ||||
|                     ]), | ||||
|               ])] | ||||
|         }) | ||||
|         class Cmp { | ||||
|           public items: any[] = [0, 1, 2]; | ||||
|         } | ||||
| 
 | ||||
|             TestBed.configureTestingModule({declarations: [Cmp]}); | ||||
|         TestBed.configureTestingModule({declarations: [Cmp]}); | ||||
| 
 | ||||
|             const engine = TestBed.get(ɵAnimationEngine); | ||||
|             const fixture = TestBed.createComponent(Cmp); | ||||
|             const cmp = fixture.componentInstance; | ||||
|         const engine = TestBed.get(ɵAnimationEngine); | ||||
|         const fixture = TestBed.createComponent(Cmp); | ||||
|         const cmp = fixture.componentInstance; | ||||
| 
 | ||||
|             fixture.detectChanges(); | ||||
|             engine.flush(); | ||||
|         fixture.detectChanges(); | ||||
|         engine.flush(); | ||||
| 
 | ||||
|             const players = getLog(); | ||||
|             expect(players.length).toEqual(3); | ||||
|         const players = getLog(); | ||||
|         expect(players.length).toEqual(3); | ||||
| 
 | ||||
|             const [p1, p2, p3] = players; | ||||
|             expect(p1.element.innerText.trim()).toEqual('0'); | ||||
|             expect(p2.element.innerText.trim()).toEqual('1'); | ||||
|             expect(p3.element.innerText.trim()).toEqual('2'); | ||||
|         const [p1, p2, p3] = players; | ||||
|         expect(p1.element.innerText.trim()).toEqual('0'); | ||||
|         expect(p2.element.innerText.trim()).toEqual('1'); | ||||
|         expect(p3.element.innerText.trim()).toEqual('2'); | ||||
| 
 | ||||
|             players.forEach(p => { | ||||
|               expect(p.keyframes).toEqual([{opacity: '0', offset: 0}, {opacity: '0.5', offset: 1}]); | ||||
|             }); | ||||
|           }); | ||||
|         players.forEach(p => { | ||||
|           expect(p.keyframes).toEqual([{opacity: '0', offset: 0}, {opacity: '0.5', offset: 1}]); | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
|       it('should cleanup :enter and :leave artifacts from nodes when any animation sequences fail to be built', | ||||
|          () => { | ||||
|  | ||||
| @ -105,7 +105,7 @@ describe('renderer factory lifecycle', () => { | ||||
| 
 | ||||
|   it('should work with a template', () => { | ||||
|     renderToHtml(Template, {}, 1, 0, null, null, rendererFactory); | ||||
|     expect(logs).toEqual(['create', 'begin', 'function create', 'function update', 'end']); | ||||
|     expect(logs).toEqual(['create', 'function create', 'function update']); | ||||
| 
 | ||||
|     logs = []; | ||||
|     renderToHtml(Template, {}); | ||||
| @ -115,8 +115,8 @@ describe('renderer factory lifecycle', () => { | ||||
|   it('should work with a template which contains a component', () => { | ||||
|     renderToHtml(TemplateWithComponent, {}, 2, 0, directives, null, rendererFactory); | ||||
|     expect(logs).toEqual([ | ||||
|       'create', 'begin', 'function_with_component create', 'create', 'component create', | ||||
|       'function_with_component update', 'component update', 'end' | ||||
|       'create', 'function_with_component create', 'create', 'component create', | ||||
|       'function_with_component update', 'component update' | ||||
|     ]); | ||||
| 
 | ||||
|     logs = []; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user