0

Lift で単純な CRUD インターフェースを実装してそれを作成するためのクリーンな方法は何ですか?

  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スニペットを完成させるのを少しためらっています。<table>リスト項目を永続化するコードは簡単ですが、 newで更新する部分にアプローチする方法がわかりません<tr>。マークアップでスニペットを汚染して、デザイナーがテーブルでやりたいことをする余地を残すことは避けたいと思います。このスニペットをどのように完成させますか?

4

2 に答える 2

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.

影響を受ける行のみを reRender する場合、それは少し難しくなります。

私はおそらく次のようなことを試してみます:

まず、特定の行の HTML を使用してテンプレートを作成します。この例では、 に入れますtemplates-hidden/rowtemplate.html。内容:

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

次に、render を変更して各 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)
  }

注: 上記の 1<tr>つ目は HTML の TR にバインドされ、2 つ目はテンプレートで指定された 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)
}

すべてが機能することを確認するためにそれをテストしていませんが、うまくいけば正しい方向に向けることができます.

于 2013-08-28T17:03:58.613 に答える
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(とても便利かもしれません、試してみてください)
  • 列ごとに個別の html-s を作成し<tr>ます。コードでは、 を使用できますdef html: NodeSeq = Templates("myHtmlFile" :: Nil).openOr(NodeSeq.Empty)。コードがthen<tr>から分離されるため、私には汚いようです。<table>
于 2013-08-28T17:01:14.883 に答える