AFSpawnService
AFSpawnService copied to clipboard
Doesn't work with EntryComponents defined in a lazy loaded module.
https://github.com/angular/angular/issues/14324
It has to do with the entry components of a lazy loaded module not being appended to the list in the app ComponentFactoryResolver.
The solution is the caller to inject it's ComponentFactoryResolver and Injector and pass it to the service. The ReflectiveInjector will need replacing at one point, but later.
`createLazyComponent(type: any, lcfr: ComponentFactoryResolver, inj: Injector, vcr: ViewContainerRef, context?: any) {
const childComponent = lcfr.resolveComponentFactory(type);
let refInjector = ReflectiveInjector
.resolveAndCreate([{provide: type, useValue: type}], inj);
let componentRef = vcr.createComponent(childComponent, 0, refInjector);
let unsubs = this._wireOutputs(childComponent, componentRef, context);
// Turn the provided inputs into an observable (if not already an observable)
let observableSymbol = getSymbolObservable(window);
let context$;
if (context && context[observableSymbol]) {
context$ = context;
} else {
context$ = new BehaviorSubject(context);
}
// Subscribe to the new observable for updated input values
unsubs.push(context$.subscribe(() => {
childComponent.inputs.forEach(i => {
if (context) {
if (context[i.propName] !== undefined) {
componentRef.instance[i.propName] = context[i.propName];
}
}
})
}));
// This function will be returned to the caller, to be called when their context is destroyed
let detach = () => {
!vcr && this.appRef.detachView(componentRef.hostView);
componentRef.destroy();
unsubs.forEach(u => u());
};
// This function will be returned to the caller, to be called when there are new values for the inputs
let next = (data) => {
if (context$ === context) {
throw `When passing an observable as a context, you cannot call the \`.next\`
function from the result. If you wish to update the values in your context,
send the data through the observable that you
passed in as the context.`;
}
context$.next(data);
};
return {
detach,
next,
}
}
`