Repository navigation
Allow to define the view_context without rendering the component #1926
Description
Activity
@Spone, @camertron @joelhawksley what do you think about this,
I have seen niche circumstances where by I would have benefited from passing in a custom view_context when rendering, I do think this is niche however, so I would like to hear your thoughts on it@reeganviljoen @mildred my gut says that this kind of functionality isn't the responsibility of ViewComponent. ViewComponent is meant to build objects that have the Single Responsibility of being passed to Rails'
render.I can see the appeal of using Slots to construct tabular data, but I think you might be better off creating some sort of PORO or model to represent your tabular data and rendering that via a ViewComponent for HTML and some other tooling for a spreadsheet format.
I agree with @joelhawksley, the motivation to add this doesn't feel particularly strong, since components aren't designed to be used like shared objects. I would personally refactor your example to extract the logic into a separate class.
Reacted by Hans Lemuet@camertron i feel the part about not rendering doesn't make sense but passing in a custom view_context when rendering may be useful in niche cases
I had recently the same need. I won't go too much in details about requirements, but I have a ViewComponent with a
titlemethod. The method uses a path helper as well.
I had to make a CSV report "with what is displayed on the web page" and the simple and logic solution for me is to runMyComponent.new.titleto get the actual title.The error message is (slightly) misleading
"#controllercan't be used during initialization, as it depends on the view context that only exists once a ViewComponent is passed to the Rails render pipeline."since I was not in an initializer, but I met this message before and knew that I had to convert path call into
Rails.application.routes.url_helpers.my_pathas I did with myI18n.tcalls.I know, it's a niche case, and probably not how is supposed to be used, but I still find it ambiguous that I cannot render my
title. I'd be fine in passing a view_context explicitly or be able to set a default one somehow.@coorasse thanks for the report!
I've opened #2217 to improve the error messaging in that case. You're totally right in that the warning is about referencing certain properties before rendering not during initialization.
More broadly, it's always been the intention that the Single Responsibility of a ViewComponent is to render content, not to expose data to other objects. I'm hesitant to add functionality to the framework that encourages such behavior. If you need logic inside a ViewComponent elsewhere, I'd encourage folks to extract that logic into another class or module.
Of course, I'm always happy to be proven wrong here ❤
I had a similar issue and I introduced a
setup_rendertest helper in my PR #2483
Feature request
I'd like to be able to do something like:
That is, a way to associate the component with a view_context so I can do things like translations or access render-specific methods, but not perform the rendering step.
Motivation
I have a component that generates a HTML table. I want to make the table downloadable as a spreadsheet, but I'd like the table generation to happen within the component itself to keep all the things at the same place.
So in my rails controller, when I want to generate the spreadsheet, I create the component, then call the spreadsheet method on it that will generate the spreadsheet file. To do that I need translations, which requires the view_context.
Workaround
In my component I can define:
Then I can use my component like this: