Open
Description
In an attempt to integrate modal handling seamlessly across web + {N} shared codebase, ModalDialogParams
presents a problem in the way it is currently designed.
Instead of:
const modalParams = new ModalDialogParams(options.context, closeCallback);
const providers = ReflectiveInjector.resolve([
{ provide: Page, useValue: page },
{ provide: ModalDialogParams, useValue: modalParams }, // let's remove this
]);
Perhaps the params could be simply lifted off the ModalDialogService
itself and do away with ModalDialogParams
altogether to do something like this:
constructor(private modal: ModalDialogService) {}
public close() {
let optionalArgs: any = {
anyData: 'test'
};
this.modal.close(optionalArgs);
}
Could look something like:
@Injectable()
export class ModalDialogService {
public static closeCallback: Function;
public context: any;
private containerRef: ViewContainerRef;
// etc.
public close(args) {
this.context = undefined; // clear any previously passed context
ModalDialogService.closeCallback(...args);
}
public showModal(type: Type<any>, options: ModalDialogOptions): Promise<any> {
let viewContainerRef = options.viewContainerRef || this.containerRef;
if (!viewContainerRef) {
throw new Error("No viewContainerRef: Make sure you pass viewContainerRef in ModalDialogOptions.");
}
const parentPage: Page = viewContainerRef.injector.get(Page);
const resolver: ComponentFactoryResolver = viewContainerRef.injector.get(ComponentFactoryResolver);
const pageFactory: PageFactory = viewContainerRef.injector.get(PAGE_FACTORY);
this.context = options.context; // allow shown components to access context
return new Promise((resolve, reject) => {
setTimeout(() => ModalDialogService.showDialog(type, options, resolve, viewContainerRef, resolver, parentPage, pageFactory), 10);
});
}
private static showDialog(
type: Type<any>,
options: ModalDialogOptions,
doneCallback,
containerRef: ViewContainerRef,
resolver: ComponentFactoryResolver,
parentPage: Page,
pageFactory: PageFactory): void {
const page = pageFactory({ isModal: true, componentType: type });
let detachedLoaderRef: ComponentRef<DetachedLoader>;
ModalDialogService.closeCallback = (...args) => {
doneCallback.apply(undefined, args);
page.closeModal();
detachedLoaderRef.destroy();
};
// etc.
Simplifying setup by only needing to work with 1 service ModalDialogService
instead of 2. It would also make tokenized setups for code sharing between web + {N} more achievable.
If this makes sense, I can offer a PR for this soon.
/cc @vakrilov