2013-08-28 25 views
0

什麼將實現提升一個簡單的CRUD接口,並使其電梯 - CRUD與設計師友好的模板和Ajax

  1. 設計師友好
  2. 阿賈克斯

一個乾淨的方式讓我們假設我們有一個觀點

<table data-lift="CrudList"> 
    <tr> 
     <td role="data">Item goes here</td> 
     <td><button role="remove" type="button">remove</button></td> 
    </tr> 
    <tr class="clearable"> 
     <td>Item two here</td> 
     <td><button type="button">remove</button></td> 
    </tr> 
    <tr class="clearable"> 
     <td>Item three!</td> 
     <td><button type="button">remove</button></td> 
    </tr> 
</table> 
<form data-lift="form.ajax"> 
    <div data-lift="CrudList.create"> 
     <input type="text" name="text"></input> 
     <button type="submit"></button> 
    </div> 
</form> 

而且片斷

object CrudList { 
    def render = { 
    def remove(item: String) =() => { 
     ListDAO.remove(item) 
     JE.JsRaw("""Some JavaScript to remove <tr> from the UI""") 
    } 

    ClearClearable & 
    "tr *" #> ListDAO.all.map(item => { 
     "role=data" #> item & 
     "role=remove" #> ajaxInvoke(remove(item)) 
    }) 
    } 

    def create = { 
    var text = "" 

    def process(): JsCmd = { 
     val item = ListDAO.create(text) 
     JsCmds.Noop // TODO: replace this with some JsCmd 
        // that will create and populate new table row in the UI 
        // without polluting the snippet with markup 
    } 

    "@text" #> SHtml.text(text, s => text = s) & 
    "button *+" #> SHtml.hidden(process) 
    } 
} 

示例可能有錯誤,純粹是爲了演示。

render片段非常簡單 - 我們修改現有標記並將列表呈現爲表格行。

我有點猶豫,要完成create的片段。保留列表項的代碼很簡單,但我不知道如何使用新的<tr>來更新<table>。我想避免使用標記留下空間讓設計人員在桌子上做他們想要的事情。你會如何完成這個片段?

回答

1

最簡單的方法是換出整個HTML表格。爲此,您可以使用SHtml中的內置函數來記憶初始轉換。

爲了做到這一點,我們會給table的ID,如:

<table data-lift="CrudList" id="mytable"> 
程式碼中

然後,你可以這樣做:

object CrudList { 
    object tableMemo extends RequestVar[Box[IdMemoizeTransform]](Empty) 

    def render = { 
    def remove(item: String) =() => { 
     ListDAO.remove(item) 
     tableMemo.get.foreach{ _.setHtml } 
    } 

    "#mytable" #> SHtml.idMemoize{ memo => 
     tableMemo(memo) 
     ClearClearable & 
     "tr *" #> ListDAO.all.map(item => { 
     "role=data" #> item & 
     "role=remove" #> ajaxInvoke(remove(item)) 
     }) 
    } 
    } 

    def create = { 
    var text = "" 

    def process(): JsCmd = { 
     val item = ListDAO.create(text) 
     tableMemo.get.foreach{ _.setHtml } 
    } 

    "@text" #> SHtml.text(text, s => text = s) & 
    "button *+" #> SHtml.hidden(process) 
    } 
} 

tableMemo.get.foreach{ _.setHtml }任何調用將重新描繪表中提供的第一次渲染髮生並設置RequestVar

如果您只希望重新調整受影響的行,那會更具挑戰性。

我可能會嘗試這樣的事:

首先,創建與HTML對於給定行的模板。在這個例子中,我們將把它放在templates-hidden/rowtemplate.html。隨着內容:

<tr> 
    <td role="data">Item goes here</td> 
    <td><button role="remove" type="button">remove</button></td> 
</tr> 

然後,我們將修改呈現給每個TR和從模板檢索該行

val rowTemplate = Templates("templates-hidden" :: "rowtemplate" :: Nil) openOr <tr></tr> 

    def render = { 
    def remove(item: String) =() => { 
     ListDAO.remove(item) 
     JsCmds.Run("$('#' + item.id).remove()") 
    } 

    ClearClearable & 
    "tr" #> { 
     "tr" #> ListDAO.all.map(item => { 
     "* [id]" #> item.id & 
     "role=data" #> item & 
     "role=remove" #> ajaxInvoke(remove(item)) 
     }) 
    }.apply(rowTemplate) 
    } 

注意:第一個<tr>以上將綁定到你的TR html,第二個將綁定到模板中指定的TR。

高清創建= {VAR 文本=「」

def process(): JsCmd = { 
    val item = ListDAO.create(text) 
    val rowNS = { 
     "* [id]" #> item.id & 
     "role=data" #> item & 
     "role=remove" #> ajaxInvoke(remove(item)) 
    }.apply(rowTemplate) 
    JsCmds.Run("tr:last").append(rowNS.toString) 
} 

"@text" #> SHtml.text(text, s => text = s) & 
"button *+" #> SHtml.hidden(process) 
} 

我沒有測試過,以確保所有的工作,但希望將指向您在正確的方向。

1

如何像這樣的做法在類?:

,場private var html: NodeSeq = NodeSeq.Empty

變化渲染方法添加到 def render(in: NodeSeq) = {html = in; ...; cssTransform.apply(in)}

create,再次重用的HTML。像。

替代我知道:

  • SHtml.memoize(可能是非常有用的,試試吧)
  • <tr>列上創建獨立的HTML-S。在代碼中,您可以使用def html: NodeSeq = Templates("myHtmlFile" :: Nil).openOr(NodeSeq.Empty)。對我來說似乎很髒,因爲<tr>代碼將與<table>分離。