Issue
I have a service which controls modal creation. Below is the code in that service which initiates modal creation, using property injection to supply the component instance with a reference to a new injector
open(type: ModalType, template: TemplateRef<any>, model?: any) {
let ref = this.modal.open(ModalContainerComponent);
let component = ref.componentInstance as ModalContainerComponent;
component.tRef = template;
component.injector = Injector.create({
providers: [
{ provide: NgForm,
useFactory: () => {
return component.form;
}
}
]
});
}
The NgForm
instance that is provided here is retrieved from the component instance as a ViewChild
because the modal service needs it elsewhere.
The modal component (component instance) has the following template:
<form
#form="ngForm"
(ngSubmit)="commit()"
[ngFormOptions]="{ updateOn: 'change' }">
<ng-container *ngIf="initialized && tRef && m && injector">
<ng-container
*ngTemplateOutlet="tRef; context: { $implicit: { m } }"
[ngTemplateOutletInjector]="injector"></ng-container>
</ng-container>
</form>
The portion containing the template outlet is conditionally rendered after view initialization, and by the time an NgForm is requested by anything in the sub-template, it should be available to the factory provider in the injector created by the modal service. Unfortunately, components in that template seem to be receiving a different injector than the one provided via ngTemplateOutletInjector
as above. The one they receive does not provide the reference to NgForm
. This results in the following error:
NullInjectorError: No provider for NgForm
I've verified that within the provider the NgForm
instance is available. I'm sure I must be missing something but as ngTemplateOutletInjector
is a new feature with little documentation it's a little unclear to me. Any help is appreciated.
Solution
After playing around with this a little bit eventually I received a parser error for the modal component's template where the template ref is passed to the template outlet:
Parser Error: Binding expression cannot contain chained expression at column 7 in [tRef; context: { $implicit: { m } }]
ngTemplateOutletInjector
is really the third input parameter of the ngTemplateOutlet
directive. Explicitly binding to all three inputs separately as follows solved the aforementioned error, and also the original problem:
<ng-container
[ngTemplateOutlet]="tRef"
[ngTemplateOutletContext]="{ $implicit: { m } }"
[ngTemplateOutletInjector]="injector"></ng-container>
Answered By - RTD
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.