Как передать параметры в on: click в Svelte?

Привязать функцию к кнопке просто и понятно:

<button on:click={handleClick}>
    Clicks are handled by the handleClick function!
</button>

Но я не вижу способа передать параметры (аргументы) функции, когда я делаю это:

<button on:click={handleClick("parameter1")}>
    Oh no!
</button>

Функция вызывается при загрузке страницы и больше никогда.

Можно ли вообще передать параметры функции, вызываемой из on:click{}?


**EDIT:**

Я только что нашел хитрый способ сделать это. Вызов функции из встроенного обработчика работает.

<button on:click={() => handleClick("parameter1")}>
    It works...
</button>

person Félix Paradis    schedule 07.10.2019    source источник
comment
Это то, о чем прямо не упоминалось даже в документации. Но да, я думаю, что это путь на данный момент .. Пока они не придумали другое решение ..   -  person Manish    schedule 07.10.2019
comment
Это не взлом, это принцип работы. Это явно упоминается в руководстве svelte.dev/tutorial/inline-handlers   -  person Rich Harris    schedule 07.10.2019
comment
Спасибо за ваши комментарии! Этот хакерский способ сделать это в конце концов не так уж и плох, но я бы осмелился сказать, что документация и руководство не очень явно об этом. Хотя, может быть, это только я.   -  person Félix Paradis    schedule 07.10.2019
comment
Как бы то ни было, причина on:click{() => clickHandler(param)} в том, как Рич сказал выше, как это работает, потому что нужно передать ссылку на функцию, которую нужно выполнить. Вызывая on:click{clickHandler(param)}, вы немедленно выполняете функцию. Это не то, что вам нужно.   -  person solidstatejake    schedule 24.08.2020


Ответы (6)


TL;DR

Просто оберните функцию-обработчик в другую функцию. Для элегантности используйте функцию стрелки.


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

Зачем мне нужна другая оболочка функции?

Если бы вы использовали только обработчик и передавали параметры, как бы это выглядело?

Наверное, примерно так:

<button on:click={handleClick("arg1")}>My awesome button</button>

Но помните, handleClick("arg1") именно так вы вызываете функцию мгновенно, и это именно то, что происходит, когда вы помещаете ее таким образом, она будет вызываться, когда выполнение достигнет этой строки, и не так, как ожидалось, НА КНОПКЕ. ..

Следовательно, вам нужно объявление функции, которое будет вызываться только событием щелчка, и внутри него вы вызываете свой обработчик с любым количеством аргументов.

<button on:click={() => handleClick("arg1", "arg2")}>
    My awesome button
</button>

Как отметил @Rich Harris (автор Svelte) в комментариях выше: Это не взлом, но то, что документация также показывает в своих руководствах: https://svelte.dev/tutorial/inline-handlers

person V. Sambor    schedule 04.04.2020
comment
для меня это не работает ‹кнопка на: click = {handleClick (arg1)}› только ‹кнопка на: click = {() =› handleClick (arg1)} › - person romanown; 11.02.2021

Рич ответил на это в комментарии, так что честь ему, но способ привязки параметров в обработчике кликов выглядит следующим образом:

<a href="#" on:click|preventDefault={() => onDelete(projectId)}>delete</a>
<script>
function onDelete (id) {
  ...
}
</script>

Чтобы предоставить дополнительную информацию для людей, которые также борются с этим, и это должно быть в документации, если это не так, вы также можете получить событие click в таком обработчике:

<a href="#" on:click={event => onDelete(event)}>delete</a>
<script>
function onDelete (event) {
  // if it's a custom event you can get the properties passed to it:
  const customEventData = event.detail

  // if you want the element, you guessed it:
  const targetElement = event.target
  ...
}
</script>

Документы / учебник Svelte: встроенные обработчики

person Antony Jones    schedule 02.11.2019
comment
Почему вы используете ссылки для кнопок, если у них нет URL-адреса? - person mikemaccana; 13.12.2019
comment
Потому что я создаю PWA, в которых есть резервные ссылки, так что это скорее причина привычки. Это может быть просто кнопка. - person Antony Jones; 14.12.2019

Я получил работу с этим:

<a href="#" on:click|preventDefault={onDelete.bind(this, project_id)}>delete</a>

function onDelete(id) {
}
person chovy    schedule 01.11.2019

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

const handleClick = (parameter) => () => {
   // actual function
} 

А в HTML

<button on:click={handleClick('parameter1')>
   It works...
</button>

Остерегайтесь каррирования

Как упоминалось в комментариях, у каррирования есть свои подводные камни. Самый распространенный из них, который в приведенном выше примере handleClick('parameter1') не запускается при нажатии, а скорее при рендеринге, возвращая функцию, которая, в свою очередь, запускается при нажатии. Это означает, что эта функция всегда будет использовать «параметр1» в качестве аргумента.

Поэтому использование этого метода будет безопасным только в том случае, если используемый параметр является некоторой константой и не изменится после рендеринга.

Это привело бы меня к другому вопросу:

1) Если это константа, использующая параметр, вы также можете использовать отдельную функцию

const handleParameter1Click = () => handleClick('parameter1');

2) Если значение динамическое, но доступно в компоненте, это все равно можно обработать с помощью отдельной функции:

let parameter1;
const handleParameter1Click = () => handleClick(parameter1);

3) Если значение является динамическим, но недоступно из компонента, потому что оно зависит от какой-либо области (например, список элементов, отображаемых в блоке #each), будет работать 'хакерский' подход. лучше. Однако я думаю, что в этом случае было бы лучше иметь элементы списка в качестве самих компонентов и вернуться к случаю №2.

В заключение: каррирование будет работать при определенных обстоятельствах, но не рекомендуется, если вы не очень хорошо осведомлены и осторожны в том, как его использовать.

person Stephane Vanraes    schedule 07.10.2019
comment
Не делай этого! Просто создайте встроенную функцию (on:click={() => handleClick('parameter1')}) - person Rich Harris; 07.10.2019
comment
Только что понял, что это предложение, на которое вы ответили. Я не рекомендую каррирование по двум причинам: во-первых, не так ясно, что происходит (люди склонны ошибочно полагать, что handleClick('parameter1') - это то, что происходит когда происходит щелчок. Во-вторых, это означает, что обработчик необходимо выполнять повторную привязку при изменении параметров, что является неоптимальным. В настоящее время существует ошибка, означающая, что она все равно не работает svelte.dev/repl/a6c78d8de3e2461c9a44cf15b37b4dda?version=3.12.1 - person Rich Harris; 07.10.2019
comment
Правда, я не знал об этой ошибке, сам с ней не сталкивался. Опять же, в кодовой базе, над которой я работаю, мы никогда не передаем такие параметры, они почти всегда являются объектами, и это, кажется, работает: svelte.dev/repl/72dbe1ebd8874cf8acab86779455fa17?version=3.12.1 - person Stephane Vanraes; 07.10.2019
comment
Я обновил свой ответ, добавив некоторые подводные камни и другие размышления. Спасибо за вклад - person Stephane Vanraes; 08.10.2019
comment
Ага, он будет работать с объектами, пока сама ссылка не изменится (и основная ошибка также будет исправлена ​​со временем) - person Rich Harris; 08.10.2019

Вот он с методом противодействия и аргументом события:

<input type="text" on:keydown={event => onKeyDown(event)} />


const onKeyDown = debounce(handleInput, 250);

async function handleInput(event){
    console.log(event);
}
person chovy    schedule 06.12.2019

При риске некропостинга перейдите на страницу https://svelte.dev/repl/08aca4e5d75e4ba7b8b05680f3d3bf7a?version=3.23.1

сортируемая таблица. Обратите внимание на передачу параметров в функцию обработки щелчка заголовка волшебным образом. Понятия не имею, почему это так. Может быть, авто-каррирование?

person emperorz    schedule 24.03.2021
comment
функция sort в этом REPL возвращает функцию, и эта функция обрабатывает щелчок. когда компонент загружен, sort вызывается дважды с именем столбца и возвращает две функции: одна будет сортировать по идентификатору, а другая - по значению. - person Antony Jones; 13.04.2021