fix(platform-server): wait for async app initializers to complete before removing server side styles (#16712)

This fixes a flicker when transitioning from server rendered page to client rendered page in lazy loaded routes by waiting for the lazy loaded route to finish loading, assuming initialNavigation on the route is set to 'enabled'.

Fixes #15716
This commit is contained in:
vikerman
2017-05-16 15:14:55 -07:00
committed by Jason Aden
parent 9a7f5d580f
commit c805082648
6 changed files with 79 additions and 31 deletions

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {APP_INITIALIZER, Inject, InjectionToken, Provider} from '@angular/core';
import {APP_INITIALIZER, ApplicationInitStatus, Inject, InjectionToken, Injector, Provider} from '@angular/core';
import {getDOM} from '../dom/dom_adapter';
import {DOCUMENT} from '../dom/dom_tokens';
@ -17,22 +17,25 @@ import {DOCUMENT} from '../dom/dom_tokens';
*/
export const TRANSITION_ID = new InjectionToken('TRANSITION_ID');
export function bootstrapListenerFactory(transitionId: string, document: any) {
const factory = () => {
const dom = getDOM();
const styles: any[] =
Array.prototype.slice.apply(dom.querySelectorAll(document, `style[ng-transition]`));
styles.filter(el => dom.getAttribute(el, 'ng-transition') === transitionId)
.forEach(el => dom.remove(el));
export function appInitializerFactory(transitionId: string, document: any, injector: Injector) {
return () => {
// Wait for all application initializers to be completed before removing the styles set by
// the server.
injector.get(ApplicationInitStatus).donePromise.then(() => {
const dom = getDOM();
const styles: any[] =
Array.prototype.slice.apply(dom.querySelectorAll(document, `style[ng-transition]`));
styles.filter(el => dom.getAttribute(el, 'ng-transition') === transitionId)
.forEach(el => dom.remove(el));
});
};
return factory;
}
export const SERVER_TRANSITION_PROVIDERS: Provider[] = [
{
provide: APP_INITIALIZER,
useFactory: bootstrapListenerFactory,
deps: [TRANSITION_ID, DOCUMENT],
useFactory: appInitializerFactory,
deps: [TRANSITION_ID, DOCUMENT, Injector],
multi: true
},
];