类视图助手未按预期输出捕获的HTML。

huangapple go评论57阅读模式
英文:

Class based view helper does not output captured HTML as expected

问题

对不起,我只能回答问题,而不能提供翻译。如果您有任何问题需要回答,请随时提问。

英文:

I am trying to create a set of view helpers for a project I am working in and as they share a lot of common code, for better or worse, I am trying to take an object oriented approach. However, I am having problems when I try to capture and render HTML.

Instead of rendering the HTML within the tag, it will render it before the tag and also render it as a string within the tag.

I want to understand why there are differences in the behaviour and what I can do to fix it (if it is even possible to)

Example 1: working functional approach

I have the following helper:

# application_helper.rb

def my_helper(summary_text, &block)
  tag.details do
    concat(tag.summary(tag.span(summary_text)))
    concat(tag.div(&block))
  end
end

In my html.erb file I have:

<%= my_helper('Summary text') do %>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
<% end %>

This will render:

<details>
  <summary>
    <span>
      Summary text
    </span>
  </summary>
  <div>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </div>
</details>

Example 2: non-working Object Oriented approach

In my helper file I have defined the class:

# helpers/my_helper.rb

require 'action_view'

class MyHelper
  include ActionView::Context
  include ActionView::Helpers

  attr_reader :summary_text

  def initialize(summary_text)
    @summary_text = summary_text
  end

  def render(&block)
    tag.details do
      concat(tag.summary(tag.span(summary_text)))
      concat(tag.div(&block))
    end
  end
end

And in my application helper I have:

# application_helper.rb

def my_helper(summary_text, &block)
  MyHelper.new(summary_text).render(&block)
end

In my html.erb file I have:

<%= my_helper('Summary text') do %>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
<% end %>

This will render:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
<details>
  <summary>
    <span>
      Summary text
    </span>
  </summary>
  <div>
    <ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>
  </div>
</details>

I would expect the Object Oriented approach to have the same result as the functional based approach.

I've had a try at debugging this in the Rails code and if I were to have a guess I think it's something to do with the output_buffer and the OO helper not using the same one as the view, but I am not sure.

答案1

得分: 1

你想要在这里做的是将视图上下文传递给构建器/装饰器/演示者/视图组件/什么东西,并在其上调用方法:

# 不要使用require - Rails组件已经通过railties加载
# 不要将其称为“Helper” - 这只会让事情更加混乱。
class ListBuilder
  attr_reader :summary_text
  attr_reader :context
  delegate :tag, :concat, to: :context

  def initialize(summary_text, context:)
    @summary_text = summary_text
    @context = context
  end

  def render(&block)
    tag.details do
      concat(tag.summary(tag.span(summary_text)))
      concat(tag.div(&block))
    end
  end
end
def list_with_summary(summary_text, &block)
  ListBuilder.new(summary_text, context: self).render(&block)
end
英文:

What you want to do here is pass the view context into the builder/decorator/presenter/view compont/thingamajigger and call the methods on it instead:

# do not use require - the Rails component are already loaded through railties
# do not call this "Helper" - that will just make things more confusing.
class ListBuilder
  attr_reader :summary_text
  attr_reader :context
  delegate :tag, :concat, to: :context

  def initialize(summary_text, context:)
    @summary_text = summary_text
    @context = context
  end

  def render(&block)
    tag.details do
      concat(tag.summary(tag.span(summary_text)))
      concat(tag.div(&block))
    end
  end
end
def list_with_summary(summary_text, &block)
  ListBuilder.new(summary_text, context: self).render(&block)
end

huangapple
  • 本文由 发表于 2023年3月31日 22:19:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899612.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定