Làm thế nào để truyền tham số vào: nhấp vào Svelte?


24

Liên kết một chức năng với một nút rất dễ dàng và đơn giản:

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

Nhưng tôi không thấy cách truyền tham số (đối số) cho hàm, khi tôi làm điều này:

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

Các chức năng được gọi là tải trang, và không bao giờ nữa.

Có thể hoàn toàn có thể truyền tham số cho hàm được gọi từ on:click{}?


BIÊN TẬP:

Tôi chỉ tìm thấy một cách hacky để làm điều đó. Gọi hàm từ một trình xử lý nội tuyến hoạt động.

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

Đó là những gì ngay cả các tài liệu đã không được đề cập rõ ràng. Nhưng vâng, đó là cách bây giờ tôi nghĩ .. Cho đến khi họ đưa ra một giải pháp khác ..
Manish

6
Đây không phải là một hack, nó hoạt động như thế nào . Nó được đề cập rõ ràng trong hướng dẫn svelte.dev/tutorial/inline-handlers
Rich Harris

3
Cảm ơn ý kiến ​​của bạn! Này "cách hacky" làm việc đó không phải là quá xấu sau khi tất cả, nhưng tôi dám nói rằng các tài liệu và hướng dẫn không phải là rất rõ ràng về vấn đề này. Có lẽ đó chỉ là tôi.
FelDev

Câu trả lời:


5

TL; DR

Chỉ cần bọc chức năng xử lý trong một chức năng khác, để sử dụng chức năng mũi tên sang trọng


Bạn phải sử dụng một khai báo hàm và sau đó gọi hàm xử lý với các đối số. Chức năng mũi tên là thanh lịch và tốt cho kịch bản này.

TẠI SAO tôi cần một hàm bọc khác?

Nếu bạn chỉ sử dụng trình xử lý và truyền các tham số, nó sẽ trông như thế nào?

Có lẽ là một cái gì đó như thế này:

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

Nhưng hãy nhớ rằng, handleClick("arg1")đây là cách bạn gọi hàm ngay lập tức và đó chính xác là những gì đang xảy ra khi bạn đặt nó theo cách này, nó sẽ được gọi khi thực thi đạt đến dòng này, và không như mong đợi, BẬT BẤM VÀO ...

Do đó, bạn cần một khai báo hàm, sẽ chỉ được gọi bằng sự kiện nhấp chuột và bên trong nó, bạn gọi trình xử lý của mình với nhiều đối số như bạn muốn.

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

Như @Rich Harris (tác giả của Svelte) đã chỉ ra trong các ý kiến ​​trên: Đây không phải là hack, nhưng đó là những gì tài liệu thể hiện trong hướng dẫn của họ: https://svelte.dev/tutorial/inline-handlers


12

Rich đã trả lời điều này trong một bình luận, vì vậy hãy ghi nhận anh ta, nhưng cách để ràng buộc các tham số trong trình xử lý nhấp chuột như sau:

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

function onDelete (id) {
  ...
}

Để cung cấp thêm một số chi tiết cho những người cũng đấu tranh với điều này và nó phải có trong tài liệu nếu không, bạn cũng có thể nhận sự kiện nhấp chuột trong một trình xử lý như vậy:

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

Tại sao bạn sử dụng liên kết cho các nút, khi chúng không có URL?
mikemaccana

Bởi vì tôi xây dựng PWAs có liên kết là dự phòng, vì vậy đó là lý do của thói quen. Nó có thể dễ dàng là một nút.
Antony Jones

1

Tôi đã làm cho nó làm việc với điều này:

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

function onDelete(id) {
}

1

Đây là một phương thức gỡ lỗi và đối số sự kiện:

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


const onKeyDown = debounce(handleInput, 250);

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

-1

Không có cách rõ ràng được đề cập trong tài liệu và giải pháp của bạn sẽ hoạt động nhưng thực sự không thanh lịch lắm. Giải pháp ưa thích của riêng tôi là sử dụng currying trong chính khối script .

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

Và trong HTML

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

Coi chừng cà ri

Như đã đề cập trong các ý kiến, cà ri có những cạm bẫy của nó. Cái phổ biến nhất trong ví dụ trên handleClick('parameter1')sẽ không được kích hoạt khi nhấp mà thay vào đó là kết xuất, trả về một chức năng lần lượt sẽ được kích hoạt. Điều này có nghĩa là hàm này sẽ luôn sử dụng 'tham số1' làm đối số.

Do đó, sử dụng phương pháp này sẽ chỉ an toàn nếu tham số được sử dụng là một hằng số và sẽ không thay đổi khi được hiển thị.

Điều này sẽ đưa tôi đến một điểm khác:

1) Nếu đó là hằng số được sử dụng một tham số, bạn cũng có thể sử dụng chức năng riêng biệt

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

2) Nếu giá trị là động nhưng có sẵn trong thành phần, điều này vẫn có thể được xử lý bằng chức năng độc lập:

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

3) Nếu giá trị là động nhưng không có sẵn từ thành phần vì điều này phụ thuộc vào một số loại phạm vi (ví dụ: danh sách các mục được hiển thị trong khối #each), 'hacky' phương pháp sẽ hoạt động tốt hơn. Tuy nhiên tôi nghĩ sẽ tốt hơn nếu trong trường hợp đó có các phần tử danh sách như là một thành phần và quay lại trường hợp # 2

Để kết luận: cà ri sẽ hoạt động trong một số trường hợp nhất định nhưng không được khuyến khích trừ khi bạn nhận thức rất rõ và cẩn thận về cách sử dụng nó.


3
Đừng làm điều này! Chỉ cần tạo một hàm nội tuyến ( on:click={() => handleClick('parameter1')})
Rich Harris

1
Chỉ cần nhận ra rằng đó là đề xuất mà bạn đang phản hồi. Lý do tôi khuyên chống lại cách tiếp cận cà ri có hai mặt - trước tiên, nó không rõ ràng ngay lập tức những gì đang xảy ra (mọi người có xu hướng cho rằng đó handleClick('parameter1')là những gì xảy ra khi nhấp chuột xảy ra , không chính xác. Thứ hai, điều đó có nghĩa là trình xử lý cần phải bật lại mỗi khi thay đổi tham số, Hiện tại không tối ưu. Hiện tại, có một lỗi, có nghĩa là dù sao nó cũng không hoạt động svelte.dev/repl/a6c78d8de3e2461c9a44cf15b37b4dda?version=3.12.1
Rich Harris

1
Đúng vậy, tôi đã không nhận thức được lỗi đó không bao giờ gặp phải nó. Sau đó, một lần nữa trong codebase tôi đang làm việc, chúng tôi không bao giờ vượt qua tham số như thế này, chúng hầu như luôn luôn là đối tượng và dường như hoạt động: svelte.dev/repl/72dbe1ebd8874cf8acab86779455fa17?version=3.12.1
Stephane Vanraes

Tôi cập nhật câu trả lời của mình với một số cạm bẫy cà ri và những phản ánh khác. Cảm ơn bạn đã nhập
Stephane Vanraes

À, nó sẽ hoạt động với các đối tượng, miễn là bản thân tham chiếu không thay đổi (và lỗi cơ bản cũng sẽ được sửa trong khóa học do)
Rich Harris
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.