2010-06-05 97 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