Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ba324cd

Browse files
author
vakrilov
committed
DetachedLoader ChangeDetection fix
1 parent 680a296 commit ba324cd

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

‎nativescript-angular/common/detached-loader.ts‎

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
import {ComponentRef, ViewContainerRef, Component, Type, ViewChild, ComponentResolver} from '@angular/core';
1+
import {ComponentRef, ViewContainerRef, Component, Type, ViewChild, ComponentResolver, ChangeDetectorRef, Host} from '@angular/core';
2+
import trace = require("trace");
23

34
type AnyComponentRef = ComponentRef<any>;
45
interface PendingLoadEntry {
56
componentType: Type;
67
resolveCallback: (AnyComponentRef) => void;
78
}
89

10+
export const CATEGORY = "detached-loader";
11+
function log(message: string) {
12+
trace.write(message, CATEGORY);
13+
}
14+
15+
916
/**
1017
* Wrapper component used for loading components when navigating
1118
* It uses DetachedContainer as selector so that it is containerRef is not attached to the visual tree.
@@ -20,10 +27,11 @@ export class DetachedLoader {
2027
private viewLoaded = false;
2128
private pendingLoads: PendingLoadEntry[] = [];
2229

23-
constructor(private compiler: ComponentResolver) {
24-
}
30+
constructor(private compiler: ComponentResolver, private changeDetector: ChangeDetectorRef) { }
2531

2632
public ngAfterViewInit() {
33+
log("DetachedLoader.ngAfterViewInit");
34+
2735
this.viewLoaded = true;
2836
this.pendingLoads.forEach(loadEntry => {
2937
this.loadInLocation(loadEntry.componentType).then(loadedRef => {
@@ -35,15 +43,30 @@ export class DetachedLoader {
3543
private loadInLocation(componentType: Type): Promise<ComponentRef<any>> {
3644
return this.compiler.resolveComponent(componentType).then((componentFactory) => {
3745
return this.containerRef.createComponent(componentFactory, this.containerRef.length, this.containerRef.parentInjector, null);
38-
});
46+
}).then((compRef) => {
47+
log("DetachedLoader.loadInLocation component loaded -> markForCheck");
48+
// Component is created, buit may not be checked if we are loading
49+
// inside component with OnPush CD strategy. Mark us for check to be sure CD will reach us.
50+
// We are inside a promise here so no need for setTimeout - CD should trigger after the promise.
51+
this.changeDetector.markForCheck();
52+
return compRef;
53+
})
3954
}
4055

4156
public loadComponent(componentType: Type): Promise<ComponentRef<any>> {
57+
log("DetachedLoader.loadComponent viewLoaded: " + this.viewLoaded);
58+
4259
// Check if called before placeholder is initialized.
4360
// Delay load if so.
4461
if (this.viewLoaded) {
4562
return this.loadInLocation(componentType);
4663
} else {
64+
// loadComponent called, but detached-loader is still not initialized.
65+
// Mark it for change and trigger change detection to be sure it will be initialized,
66+
// so that loading can conitionue.
67+
log("DetachedLoader.loadComponent -> markForCheck(with setTimeout())")
68+
setTimeout(() => this.changeDetector.markForCheck(), 0);
69+
4770
return new Promise((resolve, reject) => {
4871
this.pendingLoads.push({
4972
componentType: componentType,

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /