Replies: 1 comment 5 replies
-
Lots of good thoughts here, and you are on the same track as me. I have been torn on implementing a Your {
_component: {/* The alpine component that dispatched the event */},
title: "foo",
} The offending code is here: I will have to take a look again in the morning post-coffee. However, maybe we should have a Going back to your original problem though, setting a variable in the title. Something I want to explore is how to integrate with Alpine.store, I think it could be a really useful way of create a global state sore for exactly that sort of thing. I don't yet have a plan though. |
Beta Was this translation helpful? Give feedback.
-
I want to start a discussion about how to deal with "external" variable changes, like it is possible in HTMX using hx-swap-oob.
I often need to change something in the DOM, which is outside of the current scope (=component). Let#s imagine a component like the todo list that is part of a page. I'll simplify the page template like this:
Now let's say I want the page title to update every time the todolist adds or removes an item. With the current setup this is not possible. (It's also not possible with Django-Unicorn or sockpuppet. Only turbo-django offers a way to more or less complicatedly stream HTML over the wire to somewhere into the DOM)
But I think this is a quite common need in development, to update other variables than the current component's.
I know, this is not really a well-designed approach, adding a
{{count}}
variable outside the component that relies on the component. But it's only an example. To solve this, it would be a possibility to make a parent component that covers the whole page (in base.html) and has a{% block 'default' %}
which contains other blocks, so events can bubble up the dom and would change the "count" variable in the parent.But, this puts the components in direct contact, or even dependent on another.
What I would like to have is some kind of "loose coupling", like Django signals are doing. in e.g. Qt5 (the C++ framework) this is even better, Javascript has their events etc.
AFAIK, Tetra has the
dispatch()
method to do this - but it has to be parent element that receives that event - not all elements in the DOM receive those events.Is there a possibility how to solve this (IMHO common) problem - to update another part of the DOM when receiving an updated component HTML?
I have some ideas, don't know wether they work, I did not get them to work correctly:
Parent talk
Generate a
Page
component with a default block that contains all other stuff, including a todo component.I think this does not work with current django's blocks & extending them. Calling
self._parent.set_page_title()
would be the way to go there, but the component has to know where in the tree it is. (callself._parent.set_page_title()
? orself._parent._parent.set_page_title()
??)So this method would not scale well.
AlpineJs' $dispatch
Mind the .window modifier. This ensures that the event listener listens at the window, not the current tag.
Here, the second button works as intended. The first one, calling
_dispatch()
from the backend docs here, generates an object like thisThe Tetra documentation is incomplete here.
I don't understand how to use that in the receiving object. I can't do a
@set-title.window="title = $event.detail._component.title"
, and this would be ridiculous. An "extended JSON serialisable object" is unclear. Alpine docs say "This data will be accessible as the.detail
property of the event" - but I can't access.detail
anywhere.Any ideas to simplify this procedure?
@public.listen decorator ❤️
Components would have to implement Alpine's
x-data
and@custom-event
automatically, e.g. when using a (to be implemented)@public.listen()
decorator.This way the loose-coupling would be addressed. A component could send a simple Js event, and another component could automatically receive it using a listener on
.window
.@samwillis, Please tell me what you think about that.
Beta Was this translation helpful? Give feedback.
All reactions