JS / Coffee + HTML,设置条件类的简单方法

时间:2014-01-19 00:16:30

标签: javascript html coffeescript

所以,当我从javascript(或coffeescript,我根据具体情况使用两者)渲染html模板时,我发现我有一个非常普遍的案例似乎不必要的笨重。例如:

我有一个像这样的JS对象:

var thingy = {
  name: 'Some Thing',
  category: 'widget',
  active: true
};

我可能希望将其渲染为html,如下所示:

<div class="widget active">Some Thing</div>

总是感觉笨重的一点是将javascript中的布尔检查转换为css类字符串。我通常最终会做的是这样的事情:

function renderThing(thing) {
  var klass = thing.active ? thing.category + " active" : thing.category
  return '<div class="'+klass+'">'+thing.name+'</div>';
}

在coffeescript中,这种感觉更长,因为三元更冗长:

renderThing = (thing) ->
  klass = if thing.active then thing.category + " active" else thing.category
  '<div class="'+klass+'">'+thing.name+'</div>'

当只有一个这样的属性时,这并不是太可怕,但如果你最终遇到三到四个代码,那么代码会很快变得非常冗长。

所以,我想知道,有没有人有更简洁和/或可读的方法来做这个想法/建议?

3 个答案:

答案 0 :(得分:1)

如果我做了很多这些,那么我会写一个简单的函数,或多或少,提供我自己的“cast boolean to string”:

if_true = (f, s) ->
    return s if(f)
    return ''

然后用一些字符串插值来构建类字符串:

klass = "#{if_true(o.active, 'active')} #{o.category}"

如果您在!o.active时不喜欢杂散空间,那么您可以将该空间移动到if_true参数中:

klass = "#{if_true(o.active, 'active ')}#{o.category}"

如果你有一大堆标志,将它们的名字扔在一个数组中并使用循环理解来构建一个类名数组:

o =
    first: true
    second: true
    third: false
    fourth: undefined
    fifth: 'element'
    category: 'pancakes'

flags = [ 'first', 'second', 'third', 'fourth', 'fifth' ]

klasses = (if_true(o[f], f) for f in flags)
klasses.push(o.category)
klass = klasses.join(' ')

演示:http://jsfiddle.net/ambiguous/eGDaa/

答案 1 :(得分:1)

  

如果你只有一个这样的财产,那就不是太可怕了   最终处于有三到四个代码的情况下很快就会变得很快   冗长。

确实会。看起来像是一个使用开关分配的完美场所 - 也就是说,如果只有一个“附加”类:

score = 76
grade = switch
  when score < 60 then 'F'
  when score < 70 then 'D'
  when score < 80 then 'C'
  when score < 90 then 'B'
  else 'A'

但是这将是1输入等于1输出,这可能不是你想要的。也许你需要:

renderThing = (thing) ->
  cssClass = thing.category
  keysToCss = ["active", "disabled", "delta", "gamma", "epsilon"]

  for k,v of thing 
   if lodash.contains(keysToCss, k) # I'm using lodash here, same as Underscore
     cssClass += " #{k}" 

  "<div class='#{cssClass}'></div>"

另外,我认为一旦你开始混合标记和这样的代码,你需要开始研究像Angular这样的工具。

答案 2 :(得分:1)

检查coffeescripts loop comprehensions以迭代一堆标志并构建一个可以连接到类值的列表:

renderThing = (thing) ->
  flags = ["selected", "current", "active", "disabled", "bookmarked"];
  klasses = (f for f in flags when thing[f])
  klasses.push thing.category
  "<div class=\"#{klasses.join(" ")}\">#{thing.name}</div>"