Adding a conventional ID to view components #430
Replies: 4 comments 1 reply
-
@pinzonjulian thanks for taking the time to file this issue! This is interesting! I'd be curious to have you add this to your ApplicationComponent and use it across your application to see how it goes. I'm not sure that we can assume that ViewComponents represent a single record, or rather, any single entity, that has a unique identifier. |
Beta Was this translation helpful? Give feedback.
-
I do something similar to this, where I need to dynamically update components on a given page using JS. I did 2 things:
I didn't want to use
When I create a component it has a
This approach allows me to have multiple instances of the same component on the page and update them all dynamically. It would be nice to have a convention for the I did a quick inspect page on Github's site and it doesn't seem that Github itself is using any sort of per-component identifier, meaning you would have to wrap a larger partial or do page DOM-diffing I guess to dynamically update pieces of the page with view components? The above approach has worked well for me, and enables me to know what code maps to that component because of the naming convention I added. |
Beta Was this translation helpful? Give feedback.
-
I have exactly the same use case. Use Case<%= turbo_stream.update WidgetButtonComponent.new(widget: widget_record) do %>
... etc.
<% end %> Proposed APIvanilla rails implementation: widget = WidgetButtonComponent.new(widget: Widget.find(32) )
# ids:
dom_id( widget)
# => "widget_button_component_32"
# new widget
dom_id( WidgetButtonComponent.new( ) )
# => "new_widget_button_component"
# Classes:
dom_class( widget)
# => "widget_button_component"
dom_class( WidgetButtonComponent)
# => "widget_button_component" Why?Just as with <-- i would want to avoid this to work out dom_ids -->
<div id="<% if new_widget ? "new_widget_button_component" :
"widget_#{widget.id} " %>" > # no need for this logic here
</div> ... but why bother?Convention! Saves people from thinking, makes it faster. Thinking is exhausting. And most of us are kinda doing the same thing. And if we should want something different - then we can simply override it. Which is what we'll be doing anyway. Is it a bad idea?Will such an approach be a bad idea for the community? |
Beta Was this translation helpful? Give feedback.
-
Code Sample# Some view:
# puts @quote.id
# => 73
<div>
<%= render(Quotes::QuoteStateComponent.new(quote: quote)) %>
</div>
# renders:
# <div id="quote_state_component_73"> .... Let's update the component via a turbo_stream: # update.turbo_stream.erb
<%= turbo_stream.replace Quotes::QuoteStateComponent.new(quote: @quote) do %>
...
<% end %> Notice we don't have to target it with a All you need is a: # app/components/quotes/quote_state_component.rb
# app/components/quotes/quote_state_component.html.erb
# frozen_string_literal: true
class Quotes::QuoteStateComponent < ViewComponent::Base
def initialize(quote:)
@quote = quote
end
def model_name
OpenStruct.new param_key: 'quote_state_component'
end
def to_key
[@quote.id]
end
end Boom! In one fell swoop, I can update via stream, all my components, and have the dom ids encapsulated. I feel that the |
Beta Was this translation helpful? Give feedback.
-
I've been writing a lot of components lately that need a unique ID and I'd love to have a simple way to add it, similar to what rails does with
dom_id(instance)
I've played with the following:
The method
main_instance
could even pave the way for things like caching 🤔Beta Was this translation helpful? Give feedback.
All reactions