admin管理员组文章数量:1304137
I am looking for a way to listen to a dispatched event from a Svelte ponent within another ponent from JavaScript (and not from the on:
syntax).
Here is the code I am trying to achieve on REPL.
The expected behaviour would be to have 0 displayed in the console when the button Close 0 is clicked, and so on for the other ones.
I am looking for a way to listen to a dispatched event from a Svelte ponent within another ponent from JavaScript (and not from the on:
syntax).
Here is the code I am trying to achieve on REPL.
The expected behaviour would be to have 0 displayed in the console when the button Close 0 is clicked, and so on for the other ones.
Share Improve this question edited Jan 30, 2021 at 4:06 mantis 2151 gold badge4 silver badges17 bronze badges asked Apr 27, 2020 at 15:36 mlbichemlbiche 971 gold badge3 silver badges9 bronze badges2 Answers
Reset to default 6I went through some digging in svelte's piled code, and I found a solution to listen on svelte's handled event, but it's not pretty :)
You can (and should) dispatch your own custom event when calling onClose
, but here's the solution:
on Nested.svelte
<script context="module">
let counter = 0
</script>
<script>
import { createEventDispatcher, onMount } from 'svelte';
// add this
import { get_current_ponent } from 'svelte/internal';
let _this;
const id = counter++
const dispatch = createEventDispatcher()
/*********
and add this reactive statement
**********/
$: {
if (_this){
_this.parentNode.hosts = (_this.parentNode.hosts || []);
_this.parentNode.hosts.push(get_current_ponent());
}
}
/*********
end
**********/
function onClose() {
dispatch('close', id)
}
</script>
<!-- bind this -->
<button bind:this={_this} class='nested-button' on:click={onClose}>
Close {id}
</button>
Then in your App.svelte
<script>
import { onMount } from 'svelte'
import Nested from './Nested.svelte'
let element
onMount(() => {
// requestAnimationFrame is required!
requestAnimationFrame(() => element.hosts.forEach(nestedButton => {
nestedButton.$on('close', (e) => {
console.log(e.detail)
})
}));
})
</script>
<ul bind:this={element}>
<Nested/>
<Nested />
<Nested />
</ul>
Explanation -
the only way to bind to a svelte event is by getting a reference to the calling ponent and calling the $on
method, but currently there's no easy way of getting a ponent's reference.
so what I did was calling the svelte's internal get_current_ponent
, which will return the current ponent (but for some reason won't work when called inside onMount
).
I appended the reference to the parentNode.hosts
of the top most element in the ponent, which in this case is the ul
element.
then you can just call the $on
method for each reference in element.hosts
.
The appropriate solution however will be dispatching you own event like this:
function onClose() {
dispatch('close', id)
this.dispatchEvent(new CustomEvent('close', {detail: id}));
}
And by that achieving almost the exact same thing without messing with svelte's internals
I make use of svelte stores and reactivity:
signals.js:
import { writable } from 'svelte/store';
export const endSignal = writable({});
Sender.svelte:
<script>
import { endSignal } from './signals.js';
const signal = $endSignal;
function handleEndSignal(){
// do other stuff, then send signal
endSignal.update(()=> signal);
}
</script>
<button on:click={handleEndSignal}>The End</button>
Receiver.svelte:
<script>
import { endSignal } from './signals.js';
$: endItAll(), $endSignal;
let countEnds = 0;
function endItAll(){
countEnds +=1;
}
</script>
<p>times end signal received: {countEnds}</p>
Basically, every time we click the button in Sender.svelte, the value "endSignal" in "signals.js" is overwritten, hence in Receiver.svelte the updated variable in the "$:" statement triggers the function "endItAll()".
本文标签: javascriptListening to a dispatched event from a Svelte componentStack Overflow
版权声明:本文标题:javascript - Listening to a dispatched event from a Svelte component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741760555a2396379.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论