使用Designer Friendly模板和Ajax提升 - CRUD

时间:2013-08-28 15:10:16

标签: ajax scala templates lift

在Lift中实现简单的CRUD接口并使其成为

的简洁方法
  1. 设计师友好
  2. 的Ajax
  3. 假设我们有一个观点

    <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代码段。保留列表项的代码很简单,但我不知道如何处理使用新<table>更新<tr>的部分。我想避免使用标记来污染代码段,为设计人员留下他们想要的表格空间。你会如何完成这个片段?

2 个答案:

答案 0 :(得分:1)

这样的方法怎么样?:

在课堂上

添加字段private var html: NodeSeq = NodeSeq.Empty

将渲染方法更改为     def render(in: NodeSeq) = {html = in; ...; cssTransform.apply(in)}

create

,再次重复使用html。类似于JsAppend("id", transformation.apply(html))

我知道的替代方案:

  • SHtml.memoize(可能非常有用,请尝试一下)
  • <tr>列创建单独的html-s。在代码中,您可以使用def html: NodeSeq = Templates("myHtmlFile" :: Nil).openOr(NodeSeq.Empty)。对我来说似乎很脏,因为<tr>代码会与<table>分开。

答案 1 :(得分: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>将绑定到html中的T​​R,第二个将绑定到模板中指定的TR。

def create = {      var text =“”

 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)
}

我没有对此进行测试,以确保一切正常,但希望能指出正确的方向。