ViewComponent报错:找不到子组件模板文件或内联渲染方法
报错信息
ViewComponent::TemplateError in Welcome#show Couldn't find a template file or inline render method for FaqComponent::QuestionComponent.
该报错出现于使用view_component gem渲染嵌套组件的场景。
现有代码与配置
组件类定义
文件路径:app/components/faq_component.rb
class FaqComponent < ViewComponent::Base renders_many :questions, "QuestionComponent" class QuestionComponent < ViewComponent::Base attr_reader :question def initialize(question: "") @question = question end end end
父组件模板
文件路径:app/components/faq_component/faq_component.html.erb,报错触发位置为模板中渲染子组件q的行:
<%= content_tag :div, class: "c-faq", data: { controller: "faq" } do %> <%= content_tag :div, class: "c-card" do %> <% questions.each do |q| %> <%= content_tag :div, class: "c-card__section" do %> <button class="c-faq__question" data-faq-target="question"> <%= q.question %> <%= icon("arrow-expand", classes: "u-m-0", size: 12) %> </button> <div class="c-faq__answer"> <%= q %> <!-- 报错出现在此处 --> </div> <% end %> <% end %> <% end %> <% end %>
页面调用代码
<div class="l-container u-mb-xxl u-xs-mb-l"> <div class="l-row"> <div class="l-col-xs-26 l-col-md-24 l-col-md-offset-1"> <h3 class="u-mb-s">常见问题</h3> <%= render(FaqComponent.new) do |faq| %> <% faq.question(question: "What is ViewComponent?") do %> <p>View component is a pain because it's not working or because I'm using it for the very first time!</p> <% end %> <% end %> </div> </div> </div>
报错原因
ViewComponent 组件的渲染入口只有两种:
- 和组件类路径匹配的模板文件
- 组件类中定义的
#call实例方法作为内联渲染逻辑
当前定义的嵌套类FaqComponent::QuestionComponent既没有对应路径的模板文件,类中也没有定义call方法,框架找不到渲染入口就会抛出该错误。
解决方法
两种方案二选一即可:
- 方案1(符合常规组件开发规范):创建子组件对应的模板文件
注意因为QuestionComponent是FaqComponent的内部类,模板不能直接放在app/components根目录,需要放在父组件的同名目录下,路径为app/components/faq_component/question_component.html.erb,模板内容直接输出调用时传入的块内容即可:<%= content %> - 方案2(无需单独模板文件):在子组件类中添加内联渲染的
call方法
修改app/components/faq_component.rb中的QuestionComponent定义:class QuestionComponent < ViewComponent::Base attr_reader :question def initialize(question: "") @question = question end def call content end end
修改完成后重启应用服务即可正常渲染。
内容的提问来源于stack exchange,提问作者rony36
相关产品推荐
相关产品推荐

