rlemaigre / vue3-promise-dialog

Dialogs meet promises in Vue 3 !
MIT License
69 stars 14 forks source link

Close dialog from setup function #4

Closed hognevevle closed 2 years ago

hognevevle commented 2 years ago

Currently it seems the only way to dismiss a dialog, is to use the $close function from the template. (Possibly, you could also do this.$close from the Options API?)

Is there any way to dismiss dialogs from within setup()? My first hunch was to try import { closeDialog } from 'vue3-promise-dialog'; , but it seems the closeDialog isn't exported.

CleanShot 2022-04-08 at 13 52 31

I tried also the following workaround in my dialog component, but it throws an error when used:

const instance = getCurrentInstance();

onMounted(() => {
      setBackAction(instance?.appContext.config.globalProperties.$close);
    })

Error:

Uncaught TypeError: comp.returnValue is not a function
    at Proxy.app.config.globalProperties.$close (vue3-promise-dialog.es.js?db71:23:1)
    at eval (MessengerHeader.vue?a0c7:54:1)
    at eval (runtime-dom.esm-bundler.js?2725:1466:1)
    at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:155:1)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?d2dd:164:1)
    at HTMLAnchorElement.invoker (runtime-dom.esm-bundler.js?2725:366:1)
rlemaigre commented 2 years ago

Hello,

The proper way to fix this would be to store a reference to the currently opened dialog in a global variable (here and call it "comp"), remove $close(...) (or keep it for backward compatibility), expose closeDialog() and change it to do the following :

export function closeDialog(data?) {
    if (data === undefined) {
        data = dialogRef.value.comp.returnValue();
    }
    dialogRef.value.resolve(data);
    dialogRef.value = null;
}

This way to close a dialog, one would simply call closeDialog() from anywhere. No need to pass this, and no need anymore for a plugin, and no problem with VSCode not recognizing this.$close().

hognevevle commented 2 years ago

Thank you @rlemaigre!

Don't we already have a reference to the current dialog in the dialog variable?

rlemaigre commented 2 years ago

No unfortunately it's a reference to the type of the dialog, not to the current instance. The only way to get the reference to the instance is to change the DialogWrapper component (add a "ref" in the template) so that it knows the reference of the dialog and updates the global variable with it.

hognevevle commented 2 years ago

I've added that change to https://github.com/rlemaigre/vue3-promise-dialog/pull/5 . Would something like that work?

I couldn't quite work out the correct types to use for comp, any chance you could help with that so we can avoid any?

rlemaigre commented 2 years ago

I've released version 0.3.1 with your changes and I've updated the docs.

hognevevle commented 2 years ago

Thanks a lot :)