【问题标题】:Svelte: Get User Input Callback via Store FunctionSvelte:通过 Store 函数获取用户输入回调
【发布时间】:2022-08-07 19:45:14
【问题描述】:

我在这里尝试做的事情可能是不可能的,但作为 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 函数连接回调函数,以将模态中的用户响应传递回调用模态的位置。这可能吗?

    标签: javascript typescript callback svelte svelte-store


    【解决方案1】:

    为此,您只需传入函数并相应地调用它。

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

    我不会像这样使用单例组件,而是使用客户端组件 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 example

    【讨论】:

      【解决方案2】:

      我不确定这是否符合您的要求,但如果更少的代码比自定义对话框更重要,您可以考虑使用 vanilla 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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-28
        • 1970-01-01
        • 2017-02-18
        • 1970-01-01
        • 1970-01-01
        • 2015-07-30
        • 1970-01-01
        • 2019-08-22
        相关资源
        最近更新 更多