2010-06-05 96 views
0

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

首先,它不起作用。 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)) 

回答

1

的问题RewriteRule似乎是他们埋得太深。也就是说,一旦开始添加<tr>属性的规则,就不可能阻止它。 (至少,它不适合我)。但是,我发现了一个适用于我的递归解决方案。另外,只要有 a <tbody>里面,递归会提前结束。如果没有,我们可能有一个问题...

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> 
3

有迹象表明,我做到备用表行类两种不同的方式:

1 - 通过数据循环创建表时使用zipWithIndex - 使用jQuery的colorize plugin

2:

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

正如我已经说过了,我不想使用jQuery这一点。另外,我不想在服务器端创建索引,因为我认为奇数/偶数行是模板设计者需要关注的,而不是程序员。 (尽管如此,程序员可能会创建模板标签。) – Debilski 2010-06-07 15:42:10