Hello fellow Elixters
I am quite new to Phoenix LiveView and just started testing Surface UI. So far, it all feels very natural and well-designed. So kudos to everyone involved in building it!
Now I got stuck with something I expect to be a fairly easy and common problem.
Situation
I have a LiveView with a nested LiveComponent. For the sake if this example, let’s say the LiveComponent renders a card which should be highlighted when selected (clicked). The LiveComponent should therefore emit an event when clicked. This event should be handled both in the LiveComponent to toggle the highlighting as well as optionally within the LiveView to, say, track which cards are selected.
First of all: Does it at least make sense what I am trying to do?
Second: Currently I see two possible ways to implement it:
- Emit the event with the LiveComponent as its target (i.e.,
phx-target={@myself}
in plain LiveView, oron-click="my-click-event"
in Surface UI). Then insidehandle_event/3
toggle the card highlight, forward the event withsend(self(), ...)
to the LiveView and, in there, handle it inhandle_info/2
. This works, but has the drawback that the LiveComponent’s parent must handle the message withhandle_info/2
unless it wants its mailbox to fill up. Moreover, it would feel so much more natural if I handle the message from LiveComponent in the LiveView’shandle_event/3
as well. - Emit the event and make the LiveComponent’s parent the target – that is, the LiveView (in Surface UI via
prop my_click, :event
in the LiveComponent andon-click={@my_click}
insiderender/1
). There, catch the event inhandle_event/3
and usesend_update/3
to cause the LiveComponent to toggle the card’s highlight. Has the (IMHO) severe architectural drawback that the parent (here: LiveView) has to do the wiring so that the child (here: LiveComponent) renders as expected. Definitely don’t want to go down this road.
Both variants don’t feel too good to me. Essentially, what I would like to do is to somehow configure the phx-click
(or :on-click
in Surface UI) to target both the LiveComponent as well as the LiveView. Is that somehow possible?
Or: What’s the LiveView-idiomatic way to implement my scenario?
Best
Carsten