【问题标题】:Multiple multi-line HAML blocks多个多行 HAML 块
【发布时间】:2010-12-01 06:12:20
【问题描述】:

对 HAML 使用(故意)奇怪的多行格式,我想在我的模板中包含以下行:

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

-# and

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

但是,它们不能相互碰撞,或者它们被读取为一个单独的多行块。

-# This fails:
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

有趣的是,用换行符分隔并没有更好的效果:

-# This fails, too:
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

我发现的唯一可行的解​​决方案是在两者之间运行一个空的 Ruby 代码行。看起来真的很丑。

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
-
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

还有什么更好的吗?

【问题讨论】:

  • 更新: 最新版本的 HAML 中不需要管道,所以如果您刚刚遇到这个问题,请不要纠结于此;)

标签: ruby-on-rails haml


【解决方案1】:

这是一项功能,而不是错误。 Haml 多行代码块故意笨拙 - 包括难以一个接一个地跟进 - 因为几乎所有时间都最好将 Ruby 代码放入帮助程序中。即使助手只被调用一次,它也会让你的模板更容易阅读。例如:

def blatz_link
  call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3',
    :foo4 => 'bar4', :foo5 => 'bar5'
end

def blootz_link
  call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3',
    :foo4 => 'bar4', :foo5 => 'bar5'
end

然后在你的 Haml 中,就这样做

= blatz_link
= blootz_link

这将更具可读性和更容易理解。


如果您绝对必须在一个多行块后面跟着另一个,只需在其间添加注释:

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
-#
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

【讨论】:

  • 我最初拒绝了,但最终所有链接都变得如此笨拙(尤其是在员工区域,有一个“更多”下拉菜单用于管理大量其他模型),我只是放弃并重组代码以使其易于管理。谢谢:)
【解决方案2】:

我遇到了与此处提到的相同的问题和解决方法,并且 HAML 与多行块有关的奇怪(是的,这很奇怪)行为让我痛苦了好几次。我知道这是故意的,并且可能是为了强迫用户使他的代码更易于阅读。然而,众所周知的事实是,每个开发人员在构建代码时都有自己的偏好。 HAML 是我所知道的唯一一种试图施加此类限制的语言(c、c++、ruby、python、HTML 等)。

调用奇怪的多行处理功能而不是错误,只是表明语言设计有缺陷。最终它在用户眼中永远是一个错误。多行支持是任何主流语言的基本功能,缺少此功能只是很烦人 - 就像 M$ 回形针一样,我认为这也是一种引导用户的尝试。

话虽如此,HAML 是一种用于编写 HTML 的极其紧凑且有用的语言。我们这些(在某些情况下)喜欢多行代码块的人会喜欢至少提供某种配置选项来启用/禁用体面的多行代码块支持——不管语言设计者对“易于阅读的代码”的个人定义如何”。

在我们到达那里之前,我想我们将不得不使用“-#” hack 来解决语言问题...

【讨论】:

  • 难道这些限制不会创造一个更好的生态系统吗?它鼓励新老用户都遵循相似的风格和模式,从而实现更大的共享并让人们更快地加入项目。 “个人风格”本质上是不可扩展的。如果您永远不希望您的项目看到有贡献者的曙光,那很好,但这可以让默认习惯更具协作性。
  • 如果 HAML 风格确实是有益的。如果您可以将逻辑保留在模板中,我认为您的代码最终会更易于维护,即使用它的地方,而不必在实用程序模块中创建一次性方法。我认为在您的代码中的其他任何地方都会出现所有常见问题的过早抽象。我不确定为什么它在您的模板中是一件好事。约定会减少知识转移,但这并不意味着它们不会是一个坏主意,最终会花费每个人更多的时间。
【解决方案3】:

你可以在你的助手上使用一个块,产生任何有意义的东西。

module SomeHelper
  def call_to_helper
    foo = Foo.new
    yield foo
    # build your html here, using the foo object's attributes
  end

  class Foo
    attr_accessor :foo1, :foo2, :foo3, :foo4, :foo5
  end

end

现在在你的haml上:

= call_to_helper do |foo|
  -foo.foo1 = 'bar1'
  -foo.foo2 = 'bar2'
  -foo.foo3 = 'bar3'
  -foo.foo4 = 'bar4'
  -foo.foo5 = 'bar5'

= call_to_helper do |foo|
  -foo.foo1 = 'bar1'
  -foo.foo2 = 'bar2'
  -foo.foo3 = 'bar3'
  -foo.foo4 = 'bar4'
  -foo.foo5 = 'bar5'

【讨论】:

    【解决方案4】:

    这是一种 hack(有点),但您始终可以在链中的第 2 行、第 3 行等处使用“+”而不是“=”。

    = call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
      :foo4 => 'bar4', :foo5 => 'bar5' |
    + call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
      :foo4 => 'bar4', :foo5 => 'bar5' |
    

    【讨论】:

    • 哈哈,聪明。它绝对比卡在中间的一些随机破折号更好:P
    • 这不是更好,因为这意味着任何一个都很好。它只是不那么卑鄙。这就是为什么我在所有有发言权的项目中都使用 nodejs。
    • 在我的情况下,问题块不是=,而是%,所以这对我不起作用。
    猜你喜欢
    • 1970-01-01
    • 2016-04-25
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多