วิธีการส่งผ่านพารามิเตอร์ไปที่: คลิกใน Svelte?


24

การผูกฟังก์ชั่นเข้ากับปุ่มนั้นทำได้ง่ายและตรงไปตรงมา:

<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
นี้ไม่ได้สับมันเป็นวิธีการทำงาน มันถูกกล่าวถึงอย่างชัดเจนในบทช่วย
Rich Harris

3
ขอบคุณสำหรับความคิดเห็นของคุณ! นี้ "วิธี hacky" การทำมันจะไม่เลวร้ายหลังจากทั้งหมด แต่ฉันจะกล้าพูดว่าเอกสารและการกวดวิชาจะมีไม่มากอย่างชัดเจนเกี่ยวกับเรื่องนี้ บางทีมันอาจเป็นเพียงฉัน
FelDev

คำตอบ:


5

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


12

ที่อุดมไปด้วยได้ตอบในความคิดเห็นดังนั้นเครดิตกับเขา แต่วิธีการผูกพารามิเตอร์ในตัวจัดการการคลิกเป็นดังนี้:

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

function onDelete (id) {
  ...
}

หากต้องการให้รายละเอียดเพิ่มเติมสำหรับผู้ที่ต่อสู้กับเรื่องนี้และควรอยู่ในเอกสารหากไม่ใช่คุณสามารถรับเหตุการณ์คลิกในตัวจัดการดังกล่าวได้:

<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

เพราะฉันสร้าง PWAs ซึ่งมีลิงค์เป็นทางเลือกดังนั้นมันจึงเป็นเหตุผลของนิสัยมากกว่า มันอาจเป็นปุ่มได้อย่างง่ายดาย
Antony Jones

1

ฉันทำให้มันทำงานกับสิ่งนี้:

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

function onDelete(id) {
}

1

นี่คือวิธีการ debounce และอาร์กิวเมนต์ของเหตุการณ์:

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


const onKeyDown = debounce(handleInput, 250);

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

-1

ไม่มีวิธีที่ชัดเจนที่กล่าวถึงในเอกสารประกอบและวิธีการแก้ปัญหาของคุณจะทำงานได้ แต่ไม่สวยมาก โซลูชันที่ฉันต้องการคือใช้การแช่งในบล็อกสคริปต์

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

และในรูปแบบ HTML

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

ระวังการแกง

ดังที่ได้กล่าวไว้ในความคิดเห็นแกงกะหรี่มีข้อผิดพลาด ตัวอย่างที่พบบ่อยที่สุดซึ่งในตัวอย่างด้านบนhandleClick('parameter1')จะไม่ถูกยิงเมื่อคลิก แต่เป็นการแสดงผล แต่จะส่งคืนฟังก์ชันที่จะถูกเปิดใช้งาน onclick ซึ่งหมายความว่าการทำงานนี้จะมักจะใช้ 'พารามิเตอร์ 1' ในขณะที่มันเป็นข้อโต้แย้ง

ดังนั้นการใช้วิธีนี้จะปลอดภัยหากพารามิเตอร์ที่ใช้เป็นค่าคงที่บางชนิดและจะไม่เปลี่ยนแปลงเมื่อมีการแสดงผล

สิ่งนี้จะพาฉันไปที่จุดอื่น:

1) หากเป็นค่าคงที่ที่ใช้พารามิเตอร์คุณสามารถใช้ฟังก์ชันแยกกันได้เช่นกัน

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

2) หากค่าเป็นแบบไดนามิก แต่พร้อมใช้งานภายในส่วนประกอบสิ่งนี้สามารถจัดการได้ด้วยฟังก์ชันสแตนด์อโลน:

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

3) หากค่าเป็นแบบไดนามิก แต่ไม่พร้อมใช้งานจากองค์ประกอบเนื่องจากสิ่งนี้ขึ้นอยู่กับขอบเขตบางประเภท (เช่น: รายการของรายการที่แสดงในบล็อก #each) วิธีการ'แฮ็ค'จะทำงานได้ดีขึ้น อย่างไรก็ตามฉันคิดว่ามันจะดีกว่าถ้าในกรณีนั้นมี list-elements เป็นส่วนประกอบเองและถอยกลับไปเป็น case # 2

ในการสรุป: การแกงจะทำงานได้ในบางกรณี แต่ไม่แนะนำเว้นแต่คุณจะทราบดีและระมัดระวังในการใช้งาน


3
อย่าทำอย่างนี้! เพียงแค่สร้างฟังก์ชั่นอินไลน์ ( on:click={() => handleClick('parameter1')})
Rich Harris

1
เพิ่งรู้ว่าเป็นข้อเสนอที่คุณตอบกลับ เหตุผลที่ฉันแนะนำให้ใช้กับวิธีการปิดตาคือสองเท่า - ก่อนอื่นมันชัดเจนน้อยลงว่าเกิดอะไรขึ้น (ผู้คนมักจะคิดว่าhandleClick('parameter1')เป็นสิ่งที่เกิดขึ้นเมื่อการคลิกเกิดขึ้นอย่างไม่ถูกต้องประการที่สองหมายความว่าผู้จัดการจะต้องรีบาวด์ ซึ่งเป็นที่ไม่ดีในขณะนี้มีข้อผิดพลาดซึ่งหมายความว่าไม่ทำงานต่อไปsvelte.dev/repl/a6c78d8de3e2461c9a44cf15b37b4dda?version=3.12.1
Rich Harris

1
จริงฉันไม่ได้ตระหนักถึงข้อผิดพลาดที่ไม่เคยพบตัวเอง จากนั้นอีกครั้งใน codebase ฉันกำลังทำงานกับเราไม่เคยผ่านพารามิเตอร์เช่นนี้พวกเขามักจะเป็นวัตถุและดูเหมือนว่าจะทำงาน: svelte.dev/repl/72dbe1ebd8874cf8acab86779455fa17?version=3.12.1
Stephane Vanraes

ฉันอัปเดตคำตอบของฉันด้วยข้อผิดพลาดบางอย่างในการแก้ปัญหาและการสะท้อนกลับอื่น ๆ ขอบคุณสำหรับการป้อนข้อมูล
Stephane Vanraes

อ๋อมันจะทำงานกับวัตถุตราบใดที่การอ้างอิงไม่เปลี่ยนแปลง (และข้อผิดพลาดพื้นฐานจะได้รับการแก้ไขในหลักสูตรที่เหมาะสมเช่นกัน)
Rich Harris
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.