Svelte: заменить вложенный компонент, изменив связанную переменную

Я пишу проект Svelte, где у меня есть компонент Сообщение, который представляет какой-то объект js.

Есть возможность редактировать этот объект. Для этого я решил использовать два вложенных компонента MessageEditable и MessageReadable.

Они должны заменять друг друга в зависимости от состояния компонента Сообщение.

Проблема в том, что когда я пытаюсь сохранить результат редактирования и измените MessageEditable на MessageReadable, установив для свойства isEditing значение false. Я получаю сообщение об ошибке:

изображение ошибки из консоли

Я сделал ошибку или это нормальное поведение? Связывание - хороший подход или есть более оптимальный вариант для обмена значениями с родительскими компонентами?

Сообщение:

<div class="message">

    {#if isEditing}
    <MessageEditable bind:message bind:isEditing />
    {:else}
    <MessageReadable {message}/>
    {/if}

    <div class="message__controllers">
        <button on:click="set({isEditing: true})">Edit</button>
    </div>
</div>

<script>
    import MessageEditable from './MessageEditable.html';
    import MessageReadable   from './MessageReadable.html';

    export default {
        components:{
            MessageEditable,
            MessageReadable,
        },
        data:() => ({
            message:{
              id: '0',
              text: 'Some message text.'
            },
            isEditing: false,
        }),

    }
</script>

MessageEditable:

<form  class="message-editable" on:submit>
    <label><span >text</span><input  type="text"  bind:value=message.text required></label>
    <label><span>id</span><input  type="text" bind:value=message.id required></label>
    <div><button type="submit">Save</button></div>
</form>

<script>
    export default {
        events:{
            submit(node){
                node.addEventListener('submit', (event) => {
                   event.preventDefault();

                   this.set({isEditing: false});
                });
            },
        },
    };
</script>

MessageReadable:

<div class="message-readable">
    <p><span>text: </span>{message.text}</p>
    <p><span>id: </span>{message.id}</p>
</div>

2
908
1

Ответ:

Решено

Вероятно, лучше использовать метод, чем пользовательский обработчик событий, поскольку вы выполняете действия при отправке. Я протестировал этот код в REPL и не обнаружил возникшей ошибки. Я изменил ваши события на свойство методов и удалил функции узла.

<form  class="message-editable" on:submit="save(event)">
    <label><span >text</span><input  type="text"  bind:value=message.text required></label>
    <label><span>id</span><input  type="text" bind:value=message.id required></label>
    <div><button type="submit">Save</button></div>
</form>

<script>
    export default {
        methods: {
            save(event){
                event.preventDefault();
                this.set({isEditing: false});
            },
        },
    };
</script>

https://svelte.technology/repl?version=2.10.0&gist=d4c5f8e3864856d27a3aa8cb5b2e8710