-
Notifications
You must be signed in to change notification settings - Fork 404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A method to unwrap a ViewComponent::Base
subclass instance that is within a ViewComponent::Slot
#1737
Comments
I think we'd have to give some consideration to the situations you might want to use this for – maybe we'd end up with situations where we do things differently at the parent level depending on which component was rendered in a polymorphic slot, for example. Opening up that sort of possibility might lead to increased coupling between components, but perhaps that's a useful sharp knife to have in the box. |
I like the reader idea. I think any solution to this is going to come down to either doubling down on proxying (meaning, being better about hiding that it's a proxy), offering an escape hatch like a reader, or rearchitecting so there aren't proxy objects. The escape hatch is simplest. Getting proxy objects correct enough to nearly completely hide that it's a proxy is hard. Rearchitecting is costly and takes a lot of time, probably requiring escape hatches in the meantime. So I guess I'm definitely on board with some kind of reader that returns the component instance. |
@corasaurus-hex @boardfish this is an interesting question! Perhaps we could look at adding |
@joelhawksley you could, for sure, but what if the person would like to know middle? or second from last? or third from last? what a headache 😩 It gets worse, though, with proxies. What if the person wants access to any of the other methods on the underlying instance that are not being proxied and won't be passed along by
Oof, that's a lot... Which is all to say, adding some variation of In our case we've solved it by making our own base component: class AppComponent < ViewComponent::Base
def component_instance
self
end
end
class Cell < AppComponent
def initialize(row:)
@row = row
end
def first?
@row.cells.first.component_instance == self
end
def last?
@row.cells.last.component_instance == self
end
end
class Row < AppComponent
renders_many :cells, ->() {
Cell.new(row: self)
}
end
row = Row.new
row.with_cell{ "Content" }
row.with_cell{ "Other Content" }
row.with_cell{ "Even more content" }
a_cell = row.cells.first
a_cell.first? # => true I imagine VC could do something similar? |
Oh! And I mentioned it before but if ruby -e 'puts Class.new(BasicObject).instance_methods.sort_by(&:to_s).inspect'
[:!, :!=, :==, :__id__, :__send__, :equal?, :instance_eval, :instance_exec] It wouldn't help in this specific case, though, but I'm not sure if proxying |
Yes, there's even an existing issue for it: #1620 🙂 |
@corasaurus-hex would this pr close this issue #1753 |
@reeganviljoen it addresses the specific issue but not the general issue (specific: knowing the position of the component in the |
@corasaurus-hex I see your point, I would love to see the slot class refacrtored into the base class |
Hey everyone, just coming back to this issue today and remembering a conversation a number of the maintainers had a few months ago. The problem with adding another method to To @corasaurus-hex's point, a "perfect" proxy is probably not very feasible, and although we're considering removing the Class methodOne of the solutions we discussed was an ViewComponent::Slots.unwrap(component_instance.some_slot) Although an Slot methodAnother potential solution would be to add methods to the component class that would return the component instance instead of the slot proxy, eg: component.some_slot_instance These could be auto-generated by the existing Here's a proof-of-concept PR: #1895 |
You could also go with a method name that is very unlikely to clash with the underlying object, like |
@corasaurus-hex good idea! That's a little verbose for my taste, but we could do |
Yeah, that would work, but the length was deliberate to further reduce the chance of collisions. Totally a subjective call on how likely collision might be, but I'd think including the full library name would help. |
My concern with |
Feature request
I ran into an issue when trying to compare the equality of components wrapped in a ViewComponent::Slot.
Here's a simplified version of the problem:
That ought to return true, I think, but
@row.cells.first
returns aViewComponent::Slot
wrapping theCell
instance and so the equality check fails.So this feature request is rather open ended. There are a handful of ways I could see going with this:
Thoughts? Comments? Jeers?
The text was updated successfully, but these errors were encountered: