小能豆

当我调用模式时,为什么我的屏幕会变成空白?

javascript

我在网格中创建了一些按钮(我想动态确定其大小),现在我尝试打开对话框/模式,但我不知道为什么它不起作用。我有我的 REPL 链接可供使用,但我也会在这里分享我的文件。

REPL_FirstApp

main_app.svelte

<script>
    import SwContainer from './swContainer.svelte';
    import SwButtonIten from './swButtonIten.svelte';
    import SwDialogIten from './swDialogIten.svelte';

    let componentPositions = [
        { 
            component: SwButtonIten,
            props: { cstmLabel: 'Open Dialog 1', handleClick: openDialog1 },
            rowPos: 0,
            colPos: 0
        },
        { 
            component: SwButtonIten,
            props: { cstmLabel: 'Open Dialog 2' },
            rowPos: 0,
            colPos: 1
        }
    ];

    let dialog1IsOpen = false;
    let dialog2IsOpen = false;

    function openDialog1() {
        dialog1IsOpen = true;
    }

    function openDialog2() {
        dialog2IsOpen = true;
    }
</script>

<svelte:head>
    <title>About</title>
    <meta name="description" content="About this app" />
    <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
    />
</svelte:head>

<SwContainer numRow={2} numCol={2} {componentPositions}></SwContainer>

<SwDialogIten bind:isOpen={dialog1IsOpen} title="Dialog_1" message="etc, etc, etc" />
<SwDialogIten bind:isOpen={dialog2IsOpen} title="Diálog_2" message="etc, etc, etc" />

我的另一个问题是,通过父类调用另一个组件中的组件的最佳方法是什么?就我而言,我通过数组传递想要创建的组件。但我不知道这是否是最好的方法!

swContainer.svelte

<script>
    import { Col, Container, Row } from 'sveltestrap';
    import SwButtonIten from './swButtonIten.svelte';

    export let uniqueID = 0;
    export let numRow = 0;
    export let numCol = 0;
    export let componentPositions;

</script>

<Container>
    {#each Array(numRow) as _, rowIndex}
        <Row>
            {#each Array(numCol) as _, colIndex}
                <Col>
                    {#each componentPositions.filter(pos => pos.rowPos === rowIndex && pos.colPos === colIndex) as item}
                        <svelte:component this={item.component} {...item.props} />
                    {/each}
                </Col>
            {/each}
        </Row>
    {/each}
</Container>

swButtonIten.svelte

<script>
    import { Button } from 'sveltestrap';

    export let uniqueID = '';
    export let cstmLabel = '';
    export let rowPos = 0;
    export let colPos = 0;

    export let handleClick;

    function onClick() {
        handleClick();
    }
</script>

<Button on:click={onClick}>{cstmLabel}</Button>

swDialogIten.svelte

<script>
    import {
        Button,
        Modal,
        ModalBody,
        ModalFooter,
        ModalHeader
    } from 'sveltestrap';

    export let isOpen = false;
    export let title = '';
    export let message = '';
</script>

<Modal bind:isOpen>
    <ModalHeader>{title}</ModalHeader>
    <ModalBody>{message}</ModalBody>
    <ModalFooter>
        <Button color="secondary" on:click={() => isOpen = false}>Close</Button>
    </ModalFooter>
</Modal>

<style>
    /* styles */
</style>

事实证明,如果我以这种方式运行代码,当我单击按钮时,屏幕就会变暗,我无法执行任何其他操作!我必须关闭页面并重新打开它


阅读 120

收藏
2024-02-28

共1个答案

小能豆

在您的代码中,您在打开对话框时设置了dialog1IsOpendialog2IsOpen的状态,但在对话框组件内部,您使用了bind:isOpen={dialog1IsOpen}bind:isOpen={dialog2IsOpen}来绑定对话框的打开状态。这样做会导致对话框在打开后立即关闭,因为对话框的打开状态在初始渲染时被设置为false,而且每次状态变化时对话框都会关闭。

要解决这个问题,您可以使用局部状态来控制对话框的打开状态,并在父组件中传递回调函数来更改局部状态。这样,您就可以在父组件中控制对话框的打开状态,并且可以使用回调函数来打开或关闭对话框。

首先,您可以在swDialogIten.svelte组件中添加一个closeDialog函数,用于关闭对话框:

<script>
    import {
        Button,
        Modal,
        ModalBody,
        ModalFooter,
        ModalHeader
    } from 'sveltestrap';

    export let isOpen = false;
    export let title = '';
    export let message = '';

    export function closeDialog() {
        isOpen = false;
    }
</script>

<Modal bind:isOpen>
    <ModalHeader>{title}</ModalHeader>
    <ModalBody>{message}</ModalBody>
    <ModalFooter>
        <Button color="secondary" on:click={closeDialog}>Close</Button>
    </ModalFooter>
</Modal>

<style>
    /* styles */
</style>

然后,您可以修改main_app.svelte中的方法,以便通过传递closeDialog函数来控制对话框的打开状态:

<script>
    import SwContainer from './swContainer.svelte';
    import SwButtonIten from './swButtonIten.svelte';
    import SwDialogIten from './swDialogIten.svelte';

    let componentPositions = [
        { 
            component: SwButtonIten,
            props: { cstmLabel: 'Open Dialog 1', handleClick: openDialog1 },
            rowPos: 0,
            colPos: 0
        },
        { 
            component: SwButtonIten,
            props: { cstmLabel: 'Open Dialog 2', handleClick: openDialog2 },
            rowPos: 0,
            colPos: 1
        }
    ];

    function openDialog1() {
        dialog1IsOpen = true;
    }

    function openDialog2() {
        dialog2IsOpen = true;
    }
</script>

<svelte:head>
    <title>About</title>
    <meta name="description" content="About this app" />
    <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
    />
</svelte:head>

<SwContainer numRow={2} numCol={2} {componentPositions}></SwContainer>

<SwDialogIten bind:isOpen={dialog1IsOpen} title="Dialog_1" message="etc, etc, etc" />
<SwDialogIten bind:isOpen={dialog2IsOpen} title="Diálog_2" message="etc, etc, etc" />

现在,当您单击按钮时,将调用openDialog1openDialog2函数,并将对话框的打开状态设置为true。对话框将打开并保持打开状态,直到您点击关闭按钮。

这样修改后,您应该能够正确控制对话框的打开状态,并且不再遇到页面变暗的问题。

2024-02-28