Skip to content

ModalDialogParams - allow ability to be tokenized, provide differently or remove #538

Open
@NathanWalker

Description

@NathanWalker

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions