【问题标题】:scala: Adding attributes (odd and even rows) to xml tablescala:向xml表添加属性(奇数行和偶数行)
【发布时间】:2011-02-28 04:47:47
【问题描述】:

在 Lift 应用程序中,我想添加一个特殊标签,它采用下一个表的 <tbody> 部分,并将 oddeven 类(例如)添加到每个 <tr> 标签。当然是交替的。虽然我找到了一种为所有 <tr> 标签添加另一个属性的方法,但仍然存在一些问题(参见下面的代码)。

首先,它不起作用。 cycle.next 被调用太频繁了,所以最后,一切都是odd 行。其他问题是代码不排除内部表(因此嵌套的 <tr> 也会被转换)并且它还会影响表的 <thead> 部分。

让这段代码工作的想法? (当然,如果已经有一个基于提升的解决方案——没有 jQuery——我会很感激地接受它。)

// Helper class for looping
class Loop(val strs: String*) {
    val stream_iter = Stream.continually(strs.toStream).flatten.iterator
    def next = stream_iter.next
}

val cycle = new Loop("even", "odd")

val rr = new RewriteRule {
  override def transform(n: Node): Seq[Node] = n match {
    // match any Elem
    case elem : Elem => elem match {
        // If it’s a <tr> do some further processing
        case Elem(_, "tr", att @ _, _, _*) => 
            elem % Attribute(None, "class", Text(
                // add the attribute and concatenate with others
                List(att.get("class").getOrElse("").toString, cycle.next).reduceLeft(_+" "+_).trim
                ), Null) toSeq
        case other => other
    }
    case other => other
  }
}

val rt = new RuleTransformer(rr)

val code = <table>
  <thead><tr><td>Don’t</td><td>transform this</td></tr></thead>
  <tbody>
    <tr class="otherclass">
      <td>r1c1</td><td>r1c2</td>
    </tr>
    <tr>
      <td>r2c1</td><td>r2c2</td>
    </tr>
    <tr>
      <td>r3c1</td><td>r3c2</td>
    </tr>
  </tbody>
</table>

println(rt(code))

【问题讨论】:

    标签: xml scala scala-2.8 lift


    【解决方案1】:

    我有 2 种不同的方式来完成备用表行类:

    1 - 使用 jQuery colorize plugin

    2 - 在循环数据创建表时使用 zipWithIndex:

    doQuery.zipWithIndex.map{ case (log, i) => {  
        <tr class={if (i % 2 == 0) "even" else "odd"}>  
            <td>Data</td>  
        </tr>  
    }  
    

    【讨论】:

    • 正如我所说,我不想为此使用 jQuery。另外,我不想在服务器端创建索引,因为我认为奇/偶行是模板设计者需要关心的事情,而不是程序员。 (不过,程序员可能会为此创建模板标签。)
    【解决方案2】:

    RewriteRules 的问题似乎是它们嵌套得太深了。也就是说,一旦启动了向&lt;tr&gt; 添加属性的规则,就无法停止它。 (至少,它对我不起作用。)但是,我找到了一个适合我的递归解决方案。此外,只要 内部有一个&lt;tbody&gt;,递归就会提前停止。如果没有,我们可能会遇到问题……

    abstract class Loop {
        val stream_iter = Stream.continually(elems.toStream).flatten.iterator
        def next = stream_iter.next
        def elems: Seq[String]
    }
    class Cycle extends Loop { override def elems = List("odd", "even") }
    
    // Call this when in <tbody>
    def transformChildren(sn: Seq[Node]): Seq[Node] = {
        // Start a new cycle
        val cycle = new Cycle
        sn.map{ node => node match {
            case Elem(prefix, "tr", att, scope, ch @ _*) => 
                Elem(prefix, "tr", att, scope, ch:_*) % Attribute(None, "class", Text(
                    List(att.get("class").getOrElse("").toString, cycle.next).reduceLeft(_+" "+_).trim
                    ), Null)
            case other => other
            }
        }
    }
    
    // Look for first <tbody>, transform child tr elements and stop recursion
    // If no <tbody> found, recurse
    def recurse(sn: NodeSeq): NodeSeq = sn.map{ node =>
        node match {
            case Elem(prefix, "tbody", att, scope, ch @ _*)
                => Elem(prefix, "tbody", att, scope, transformChildren(ch):_*)
            case Elem(prefix, label, att, scope, ch @ _*)
                => Elem(prefix, label, att, scope, recurse(ch):_*)
            case other => other
        }
    }
    
    val code = <table>
      <thead><tr><td>Don’t</td><td>transform this</td></tr></thead>
      <tbody>
        <tr class="otherclass">
          <td>r1c1</td><td>r1c2</td>
        </tr>
        <tr>
          <td><table><tbody><tr><td>Neither this.</td></tr></tbody></table></td><td>r2c2</td>
        </tr>
        <tr>
          <td>r3c1</td><td>r3c2</td>
        </tr>
      </tbody>
    </table>
    
    println(recurse(code))
    

    给予:

    <table>
      <thead><tr><td>Don’t</td><td>transform this</td></tr></thead>
      <tbody>
        <tr class="otherclass odd">
          <td>r1c1</td><td>r1c2</td>
        </tr>
        <tr class="even">
          <td><table><tbody><tr><td>Neither this</td></tr></tbody></table></td><td>r2c2</td>
        </tr>
        <tr class="odd">
          <td>r3c1</td><td>r3c2</td>
        </tr>
      </tbody>
    </table>
    

    【讨论】:

      猜你喜欢
      • 2012-06-06
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 2021-04-22
      相关资源
      最近更新 更多