Svelte - входное значение не всегда обновляется

Я пытаюсь создать компонент ввода в Svelte, где значение обновляется функцией JavaScript. Однако, если новое значение совпадает со старым, Svelte не будет обновлять входной элемент.

Например, этот компонент должен ограничивать ввод только числами. Если бы вы набрали 123abc, тогда на входе отобразится 123abc, а для переменной value будет всего 123.

<script>
    let value = ''
    
    const handleInput = (event) => {
        value = event.currentTarget.value.replace(/[^\d]/gu, '')
    }
</script>

<input {value} type='text' on:input={handleInput} />

<p>
    Value: "{value}"
</p>

Есть ли способ всегда сделать входное значение равным переменной value?

Попытки решения

  • Используйте атрибут HTML pattern. Хотя это работает для этого примера, это не будет работать для общего случая, который я пытаюсь решить.
  • Могу просто сказать event.currentTarget.value = value. Это работает отлично, но не похоже на Svelte.
  • bind:value имеет те же проблемы, что и прослушиватель событий (например, $: value = value.replace(/[^\d]/gu, '')). Кроме того, в общем случае bind:value у меня не сработает, поскольку я сравниваю предыдущее и обновленное значение.

Связанный


person Nick    schedule 09.05.2021    source источник


Ответы (3)


Нет ничего плохого в том, чтобы делать event.currentTarget.value = value это может не казаться стройным, но это вполне приемлемо.

person Stephane Vanraes    schedule 10.05.2021

В вашем примере вы не использовали bind:value и объявляете value на свой ввод, но вместо этого вы можете использовать этот метод

REPL

<script>
    let value = ''
    
    $: sanitized = value.replace(/[^\d]/gu, '')
</script>


<input bind:value />

<p>
    display value: {value}
</p>

<p>
    display value: {sanitized}
</p>
person Shriji Kondan    schedule 10.05.2021
comment
Тем не менее, это все еще та же проблема. Вы по-прежнему можете вводить буквы во входные данные. Да, в очищенном значении этих букв не будет, но на входе они все равно будут отображаться. Не упоминал об этом в вопросе (поэтому я обновлю его), но мне также нужно использовать прослушиватель событий в этом случае, а не bind:value. - person Nick; 10.05.2021

Если вы не хотите обновлять event.currentTarget.value напрямую, это тоже сработает.

const handleInput = (event) => {
    value = event.currentTarget.value;
    value = value.replace(/[^\d]/gu, '');
}
person Geoff Rich    schedule 10.05.2021