Svelte:通过存储函数获取用户输入回调



我在这里尝试做的事情可能是不可能的,但作为Svelte的新手,我希望它是。😄

我在组件中有一个删除按钮,它打开一个全局可用的模态,作为一个确认对话框。模态组件在我的__layout.svelte中,所以我可以从我的应用程序中的任何地方调用它。

//=== 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}

这是我的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
})
}

最后,这是我的组件在我的应用程序中,我实际上启动删除过程通过点击一个链接,显示删除确认模式:

//=== 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>

我不清楚如何通过我的confirmTrash函数连接回调函数,将用户在模态中的响应传递回调用模态的地方。这可能吗?

要使其工作,您只需传入函数并相应地调用它。

//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,
})
}

然后在组件中调用:

<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>

REPL例子我不会像这样使用单例组件,而是使用客户端组件API创建新实例。它不那么冗余,导致更清洁的生命周期和更少不必要的全局状态。

示例:

<!-- 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();
});
})
}

用法:

<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>

REPL例子

我不确定这是否符合您的要求,但如果更少的代码比自定义对话框更重要,您可以考虑使用普通的window.confirm()函数。在svelte.js中,它可能看起来像这样:

<script>
const handleClick = () => {
if (window.confirm('Are you sure?')) {
// action confirmed, let's do this
}
}
</script>
<button on:click={handleClick}>Click me!</button>

最新更新