Пример работы bind:value на основе each блока.
Код ниже:
— формирует таблицу через each из данных, которые приходят с бэкенда;
— сохраняет введенные данные из input и отправляет их на бэк.
В данном коде реализация только фронта, демонстрирует работу svelte. То что происходит на бэкенде, здесь не важно и приводится для иллюстрации.
1. Блок JS
Здесь есть важный момент. Нам обязательно надо сложить полученные данные через onMount. В ином случае svelte не будет работать с bind, когда нам надо будет сохранить данные тем способом, который приведен ниже.
Получаем данные с бэкенда:
import {onMount} from "svelte";
import {getFetchOther} from '../../main';
let settings = [];
onMount(async () => {
getFetch('settings/get-user-timers/').then((r) => {settings = r});
});
Функция сохранения, которая будет срабатывать автоматически при каждом вводе данных в инпут:
function changeValue(setting) {
getFetchOther('settings/save_user_timer/' + setting.name + '/' + setting.timer + '/' + setting.percent);
}
</script>
2. Блок Svelte
Здесь выводится таблица из данных в переменной settings.
Конструкция on:change={changeValue(setting)}, при изменении содержимого input отправляет данные в функцию changeValue (выше). Она, в свою очередь, отправляет данные для сохранения на бэкенд.
Теги input можно заменить на textarea.
<div class="header">
<div class="cell title name">Название</div>
<div class="cell title timer">Таймер (в мин)</div>
<div class="cell title percent">Коофициент в %</div>
</div>
<div class="body">
{#each settings as setting, i}
<div class="item">
<div class="cell name">{setting.name}</div>
<div class="cell timer">
<input type="text" bind:value="{setting.timer}" on:change={changeValue(setting)}>
</div>
<div class="cell percent">
<input type="text" bind:value="{setting.percent}" on:change={changeValue(setting)}>
</div>
</div>
{/each}
</div>
</div>
3. Svelte + contenteditable
Этот вариант мне нравится больше всего. Не нужны никакие input или textarea. Можно прямо в блоке div редактировать данные и сохранять их.
on:change в этом случае меняется на on:input и bind:value меняется на bind:innerHTM.
Убираем теги в contenteditable при вставке из буфера обмена
Для того чтобы в contenteditable из буфера обмена не генерировались и не вставлялись лишние теги добавим функцию:
e.preventDefault();
// Получаем из буфера обмена данные в виде простого текста
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
// Осуществляем вставку самостоятельно
document.execCommand("insertHTML", false, text);
}
На js это было бы так:
// Отменяем вставку
e.preventDefault();
// Получаем из буфера обмена данные в виде простого текста
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
// Осуществляем вставку самостоятельно
document.execCommand("insertHTML", false, text);
});
Убираем вставку DIV по клавише Enter из contenteditable
if (e.key === 'Enter') {
e.preventDefault();
document.execCommand('insertHTML', false, '<br><br>');
}
}
Разбивка данных по key и value
{/each}