简体   繁体   English

为什么编辑按钮不起作用? 苗条

[英]Why is the edit button not working? Svelte

In the below code, why is the edit button for the invidual todos not working?在下面的代码中,为什么个别待办事项的edit按钮不起作用? I have it bound to the function editTodo which sets the isEdited object property to true.我将它绑定到 function editTodoisEdited object 属性设置为 true。

It works when I declare the function inline, eg: <button on:click='{() => isEdited = true}> , but not by seperating the function ( <button on:click='{() => editTodo(isEdited)}> ).它在我声明 function 内联时起作用,例如: <button on:click='{() => isEdited = true}> ,但不是通过分隔 function ( <button on:click='{() => editTodo(isEdited)}> )。

Could anyone explain why that is and adjust the below code so that editing works with the separate function?谁能解释为什么会这样并调整下面的代码,以便编辑可以使用单独的 function?

The code:编码:

<script>
    let todos = [
        {
            desc: 'Get some groceries for cooking',
            isDone: false,
            isEdited: false,
        },
        {
            desc: 'Wash the dishes and clean the house',
            isDone: false,
            isEdited: false,
        },
    ];
    
    let newTodo;
    function createTodo() {
        todos = [...todos, {desc: newTodo, isDone: false, isEdited: false}];
        newTodo = null;
    }
    
    function editTodo(isEdited) {
        isEdited = true;
    }
    
    function deleteTodo(desc) {
        todos = todos.filter(todo => todo.desc !== desc);
    }
    
    $: console.log(todos);
</script>

<h1>
    Todoapp
</h1>
<form on:submit|preventDefault='{createTodo}'>
    <label for='create-todo' class='create-todo-label'>
        Create a new todo:
    </label>
    <input bind:value='{newTodo}' type='text' placeholder='Do something' id='create-todo' required />
    <button>
        Create
    </button>
</form>

{#if todos.length !== 0}
    <h2>
        Your todos:
    </h2>
{/if}

<ul>
    {#each todos as {desc, isDone, isEdited}, index}
        <li>
            <label for='{index}' class:done='{isDone}'>
                {desc}
            </label>
            <input id='{index}' bind:checked='{isDone}' type='checkbox' />
        </li>
    
        <button on:click={() => editTodo(isEdited)}>
            Edit
        </button>
        {#if isEdited}
            <textarea cols='30' rows='5' bind:value='{desc}' />
        {/if}
    
        <button on:click='{() => deleteTodo(desc)}'>
            Delete
        </button>
    {/each}
</ul>

<style>
    .create-todo-label {
        margin-block-end: 0.25rem;
    }
    
    label {
        max-inline-size: fit-content;
    }
    
    label.done {
        text-decoration: line-through;
    }
</style>

Iam not an svelte expert, but while looking into your code, you're just sending the parameter and changing the parameter to true, which wont reflect in actual todos array, I tried the below method and it worked我不是一个苗条的专家,但是在查看您的代码时,您只是发送参数并将参数更改为 true,这不会反映在实际的 todos 数组中,我尝试了以下方法并且它有效

<button on:click={() => editTodo(index)}>
  Edit
</button>
function editTodo(index) {      
  todos[index].isEdited = true;
}

Svelte does something here which will not work in regular JS, namely destructuring an object and then modifying the destructured properties would not affect the source object. Svelte 在这里做了一些在常规 JS 中不起作用的事情,即解构 object,然后修改解构后的属性不会影响源 object。 So the fact that bind:checked='{isDone}' works is more unexpected than editTodo not working.因此, bind:checked='{isDone}'起作用的事实比editTodo不起作用更出乎意料。

Declaring a function like editTodo creates a new lexical scope in which the argument is decoupled from what it originally referred to.像 editTodo 一样声明editTodo会创建一个新的词法 scope,其中的参数与其最初所指的内容分离。 In plain JS, assigning a new value to a function argument will simply do nothing to the original source of the argument.在普通 JS 中,为 function 参数分配一个新值只会对参数的原始来源没有任何作用。

The same appears to be true here.这里似乎也是如此。 By invoking a function, Svelte's magic association between the value and its source breaks.通过调用 function,Svelte 在值与其源之间的神奇关联被打破。

You can use an ID or the index to find the correct element in the array and update that.您可以使用 ID 或索引在数组中找到正确的元素并对其进行更新。 Or instead of destructuring the items you can pass the item and replace it in the array with an updated version (using object identity to find it, instead of ID or index).或者,您可以传递项目并将其替换为更新版本(使用 object 标识来查找它,而不是 ID 或索引),而不是解构项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM