Parametreler nasıl iletilir: Svelte'de tıklayın?


24

Bir işlevi bir düğmeye bağlamak kolay ve basittir:

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

Ama bunu yaptığımda, işlev (parametreleri) işlevine geçmek için bir yol görmüyorum:

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

İşlev sayfa yüklenirken çağrılır ve bir daha asla.

Parametreleri denilen fonksiyona geçirmek mümkün müdür on:click{}?


DÜZENLE:

Bunu yapmak için acayip bir yol buldum. İşlevi bir satır içi işleyiciden çağırmak çalışır.

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

Bu, belgelerin bile açıkça bahsetmediği şeydir. Ama evet şu an için bu bence .. Onlar farklı bir çözüm gelene kadar ..
Manish

6
Bu bir hack değil, nasıl çalışıyor . Svelte.dev/tutorial/inline-handlers
Rich Harris

3
Yorumlarınız için teşekkürler! Sonuçta bu "hacky yolu" o kadar da kötü değil, ama dokümanlar ve öğretici bu konuda çok açık olmadığını söyleyebilirim . Belki de sadece benim.
FelDev

Yanıtlar:


5

TL; DR

Sadece işleyici işlevini başka bir işleve sarın, şıklık için ok işlevini kullanın


Bir işlev bildirimi kullanmanız ve ardından işleyiciyi bağımsız değişkenlerle çağırmanız gerekir. Ok işlevi zarif ve bu senaryo için iyidir.

NEDEN başka bir işlev sarmalayıcısına ihtiyacım var?

Sadece işleyiciyi kullanır ve parametreleri iletirseniz, nasıl görünür?

Muhtemelen böyle bir şey:

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

Ancak unutmayın, handleClick("arg1")işlevi anında bu şekilde çağırırsınız ve bu şekilde koyduğunuzda tam olarak ne olur, yürütme beklendiği gibi değil , bu satıra ulaştığında çağrılır .

Bu nedenle, yalnızca click olayı tarafından çağrılacak olan bir işlev bildirimine ihtiyacınız vardır ve bunun içinde işleyicinize istediğiniz sayıda argümanla çağırırsınız.

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

@Rich Harris'in (Svelte'nin yazarı) yukarıdaki yorumlarda belirttiği gibi: Bu bir hack değil, belgelerin eğitimlerinde de gösterdiği şeydir: https://svelte.dev/tutorial/inline-handlers


12

Rich bunu bir yorumda yanıtladı, bu yüzden ona kredi verin, ancak bir tıklama işleyicisindeki parametreleri bağlama yolu aşağıdaki gibidir:

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

function onDelete (id) {
  ...
}

Ayrıca bu mücadele eden insanlar için bazı ekstra ayrıntı sağlamak için, ve gerektiği Değilse, ayrıca böyle bir işleyici tıklama olayını alabilirsiniz docs olmak:

<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'si olmadığında neden düğmeler için bağlantılar kullanıyorsunuz?
mikemaccana

Geri dönüş olarak bağlantıları olan PWA'lar oluşturduğumdan, bu daha çok alışkanlık sebebidir. Kolayca bir düğme olabilir.
Antony Jones

1

Ben bununla çalıştım:

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

function onDelete(id) {
}

1

İşte bir debounce yöntemi ve olay argümanı ile:

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


const onKeyDown = debounce(handleInput, 250);

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

-1

Belgelerde açık bir yol yoktur ve çözümünüz işe yarayacaktır, ancak gerçekten çok zarif değildir. Kendi tercih çözümü kullanmaktır Currying içinde komut bloğunun kendisi.

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

Ve HTML'de

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

Körilere dikkat edin

Yorumlarda belirtildiği gibi, körelmenin kendine özgü tuzakları vardır. Yukarıdaki örnekte en yaygın olanı handleClick('parameter1')tıklama sırasında değil, oluşturma sırasında tetiklenecek ve ardından tıklatılacak bir işlev döndürülecektir. Bu, bu işlevin bağımsız değişken olarak her zaman 'parametre1'i kullanacağı anlamına gelir .

Bu nedenle, bu yöntemi kullanmak, yalnızca kullanılan parametre bir tür sabitse ve oluşturulduktan sonra değişmeyecekse güvenli olacaktır.

Bu beni başka bir noktaya getirir:

1) Sabit bir parametre kullanılıyorsa, ayrı bir işlev de kullanabilirsiniz

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

2) Değer dinamikse ancak bileşen içinde mevcutsa, bu yine de bağımsız bir işlevle ele alınabilir:

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

3) Değer dinamikse ancak bileşen tarafından kullanılamıyorsa, bu bir tür kapsama bağlıysa (örneğin: #each bloğunda oluşturulan öğelerin listesi) 'hacky' yaklaşımı daha iyi çalışır. Ancak, bu durumda liste öğelerinin bir bileşen olarak kendilerine sahip olması ve 2. duruma geri dönmenin daha iyi olacağını düşünüyorum.

Sonuç olarak: körleme belirli koşullar altında işe yarayacaktır, ancak nasıl kullanılacağı konusunda çok iyi farkında ve dikkatli olmadığınız sürece önerilmez.


3
Bunu yapma! Yalnızca bir satır içi işlev ( on:click={() => handleClick('parameter1')}) oluşturun
Rich Harris

1
Yanıt verdiğiniz teklifin bu olduğunu fark ettiniz. Körelme yaklaşımına karşı tavsiyede bulunmamın sebebi iki yönlüdür - birincisi, ne olduğunu daha az netleştirir (insanlar , tıklama yanlış olduğundahandleClick('parameter1') ne olduğunu varsayma eğilimindedir) İkincisi, parametreler değiştiğinde işleyicinin yeniden bağlanması gerektiği anlamına gelir. Şu anda, yine de çalışmayan bir hata var, yani svelte.dev/repl/a6c78d8de3e2461c9a44cf15b37b4dda?version=3.12.1
Rich Harris

1
Doğru, bu hatanın kendimle hiç karşılaşmadığının farkında değildim. Sonra tekrar üzerinde çalıştığım kod tabanında asla böyle bir parametre geçmiyoruz
Stephane Vanraes

Cevabımı bazı kör edici tuzaklar ve diğer yansımalar ile güncelledim. Giriş için teşekkürler
Stephane Vanraes

Ah evet, referansın kendisi değişmediği sürece nesnelerle birlikte çalışacaktır (ve altta yatan hata da zamanında düzeltilecektir)
Rich Harris
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.