如何将参数传递给on:在Svelte中单击?


23

将功能绑定到按钮既简单又直接:

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

但是在执行此操作时,我看不到将参数(参数)传递给函数的方法:

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

该函数在页面加载时调用,不再调用。

是否有可能将参数传递给从中调用的函数on:click{}


编辑:

我只是找到了一种方法。从内联处理程序调用该函数即可。

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

多数民众赞成在连文档都没有明确提到。但是,是的,这就是我现在想的方式。.直到他们提出不同的解决方案
。.– Manish

6
这不是黑客,而是它的工作方式。教程svelte.dev/tutorial/inline-handlers中
Rich Harris,

3
感谢您的意见!这样做的“ hacky方式”毕竟还不错,但是我敢说文档和教程对此并不十分明确。也许只是我一个人。
FelDev

Answers:


4

TL; DR

只需将处理程序函数包装在另一个函数中,为优雅起见,请使用箭头函数


您必须使用函数声明,然后使用参数调用处理程序。箭头功能很优雅,在这种情况下很好。

为什么需要另一个函数包装器?

如果仅使用处理程序并传递参数,它将是什么样?

大概是这样的:

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

但是请记住,handleClick("arg1")这就是您立即调用函数的方式,这正是您以这种方式表示的情况,当执行到达此行(而不是按预期的那样)时,将按ON键进行调用...

因此,您需要一个函数声明,该函数声明只能由click事件调用,并且在函数声明中您可以根据需要调用具有尽可能多参数的处理程序。

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

正如@Rich Harris(Svelte的作者)在上面的评论中指出的:这不是黑客,而是文档在其教程中也显示的内容:https : //svelte.dev/tutorial/inline-handlers


12

Rich已在评论中回答了这个问题,因此请相信他,但是在单击处理程序中绑定参数的方法如下:

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

function onDelete (id) {
  ...
}

要为也为此感到困惑的人们提供一些额外的细节,如果不是,应该在文档中提供,您也可以在这样的处理程序中获取click事件:

<a href="#" on:click={event => onDelete(event)}>delete</a>

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
  ...
}

如果没有URL,为什么要使用按钮的链接?
mikemaccana

因为我构建的PWA具有作为后备链接的链接,所以这更是一种习惯。它很容易是一个按钮。
安东尼·琼斯

1

我得到它与此工作:

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

function onDelete(id) {
}

1

这是带有去抖动方法和事件参数的:

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


const onKeyDown = debounce(handleInput, 250);

async function handleInput(event){
    console.log(event);
}

-1

文档中没有提到明确的方法,您的解决方案可以使用,但确实不是很好。我自己的首选解决方案是在脚本块本身中使用curring

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

并在HTML中

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

当心咖喱

正如评论中所提到的,curry有其陷阱。在上面的示例中,最常见的一个在handleClick('parameter1')单击时不会被触发,而是在渲染时被触发,返回一个函数,该函数又会在onclick时被触发。这意味着该函数将始终使用“ parameter1”作为其参数。

因此,仅当使用的参数是某种常量并且使用该参数后才会更改时,使用此方法才是安全的。

这将使我想到另一点:

1)如果它是使用参数的常量,则也可以使用单独的函数

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

2)如果该值是动态的但在组件内可用,则仍可以使用独立函数来处理:

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

3)如果该值是动态的,但由于依赖于某种范围(例如,在#each块中呈现的项目列表)而无法从组件中获取,则“ hacky”方法会更好。但是我认为在这种情况下最好将list-elements作为组件本身并回到案例2

结论:在某些情况下可以进行欺骗,但是除非您非常了解并谨慎使用它,否则不建议使用它。


3
不要这样!只需创建一个内联函数(on:click={() => handleClick('parameter1')}
Rich Harris,

1
刚刚意识到这就是您正在响应的建议。对钻营方法的原因,我的建议是双重的-第一,它不是立即清除所发生的事情(人们往往以为handleClick('parameter1')是发生了什么时,点击发生的,不正确其次,这意味着处理器需要是反弹时参数的变化,目前,存在一个错误,这意味着无论如何svelte.dev/repl/a6c78d8de3e2461c9a44cf15b37b4dda?version=3.12.1
Rich Harris,

1
是的,我不知道自己从未遇到过该错误。然后再次在代码库中工作,我们永远不会传递这样的参数,它们几乎总是对象,并且似乎可以正常工作:svelte.dev/repl/72dbe1ebd8874cf8acab86779455fa17?version=3.12.1
Stephane Vanraes,

我用一些令人毛骨悚然的陷阱和其他反思来更新我的答案。感谢您的输入
斯特凡Vanraes

是的,只要引用本身不变(并且潜在的错误也将在适当的时候得到修复),它就可以与对象一起使用
Rich Harris
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.