Lo que estoy tratando de hacer aquí puede no ser posible, pero como recién llegado a Svelte, espero que lo sea. 😄
Tengo un botón de eliminación en un componente que abre un modal disponible globalmente que sirve como cuadro de diálogo de confirmación. El componente modal está en mi __layout.svelte , por lo que puedo invocarlo desde cualquier lugar de mi aplicación.
//=== Modal.svelte === <script lang="ts"> import { modal, confirmTrash } from '$lib/stores/modal' //Do a bunch of stuff to customize the modal... </script> {#if modal.show} <h2>{$modal.title}</h2> <p>{$modal.message}</p> <button on:click={() => { send confirmation that the delete was confirmed }>{$modal.button}</button> {/if} Aquí está mi tienda modal :
//=== modal.ts === import { writable } from 'svelte/store' //Customize the modal's state export const modal = writable({ title: '', message: '', button: '', mode: '', show: false }) //Convenience function for showing the trash confirmation modal export function confirmTrash(modalTitle: string, modalMessage: string, buttonText: string){ modal.set({ title: modalTitle, message: modalMessage, button: buttonText, mode: 'trash', show: true }) }Por último, aquí está mi componente en mi aplicación donde realmente inicio el proceso de eliminación haciendo clic en un enlace que muestra el modal de confirmación de eliminación:
//=== Component.svelte === <script lang="ts"> import { confirmTrash } from '$lib/stores/modal' </script> <a href="#trash" on:click={() => { confirmTrash('Trash Title', 'Message goes here.', 'Delete', function(result){ //I want to be able to know ** here ** if the user clicked "Delete" console.log(result) //??? }) }} >Trash</a> No tengo claro cómo conectar una función de devolución de llamada a través de mi función confirmTrash para pasar la respuesta del usuario en el modal de regreso a donde se invocó el modal. es posible?
Para que esto funcione, solo tiene que pasar la función y llamarla en consecuencia.
//Customize the modal's state export const modal = writable({ title: '', message: '', button: '', mode: '', show: false, callback: (result: boolean) => { }, }) //Convenience function for showing the trash confirmation modal export function confirmTrash( modalTitle: string, modalMessage: string, buttonText: string, callback: (result: boolean) => void, ){ modal.set({ title: modalTitle, message: modalMessage, button: buttonText, mode: 'trash', show: true, callback, }) }Luego llámalo en el componente:
<script> // ... function onButton(result) { $modal.show = false; $modal.callback(result); } </script> <!-- ... --> <button type=button on:click={() => onButton(false)}>Cancel</button> <button type=button on:click={() => onButton(true)}>{$modal.button}</button>No usaría un componente singleton como este, pero crearía nuevas instancias usando la API del componente del lado del cliente. Es menos redundante, conduce a un ciclo de vida más limpio y a un estado global menos innecesario.
Ejemplo de eso:
<!-- Modal.svelte --> <script> import { createEventDispatcher } from 'svelte'; export let title; export let message; export let button = 'OK'; const dispatch = createEventDispatcher(); </script> <div> <strong>{title}</strong> <p>{message}</p> <button type=button on:click={() => dispatch('result', false)}>Cancel</button> <button type=button on:click={() => dispatch('result', true)}>{button}</button> </div> // modal.js import Modal from './Modal.svelte'; export function confirm(options) { return new Promise(resolve => { const modal = new Modal({ target: document.body, props: options, }); modal.$on('result', e => { resolve(e.detail); modal.$destroy(); }); }) }Uso:
<script> import { confirm } from './modal.js'; async function onShow() { const confirmed = await confirm({ title: 'Confirmation', message: 'You sure?', }); if (confirmed == false) return; alert('Confirmed!'); } </script> <button type=button on:click={onShow}>Show</button>