我开始玩Lift了。我想创建一个基本应用程序,它通过输入字段从用户获取输入,对该输入执行数据库搜索,并获取该数据库搜索的结果并创建一个对象列表,然后它绑定到某些HTML代码。
我只需要帮助绑定部分,但首先需要一些背景信息。
我有一个List [Node]:
case class Node(aname:String, adata:String) {..}
我有这个html绑定到:
<div class="lift:helloWorld.displayNodes">
<div>
<div><li><B>Node:</B></li></div>
<div>Name: <node:name></node:name></div>
<div>Data: <node:data></node:data></div>
<BR>
</div>
</div>
问题是这段代码从代码段调用我的方法displayNodes并传入其中。这样我可以绑定它,因为我有html代码。所以我这样绑定:
//this method is called from the index.html and
def displayNodes(html : NodeSeq) : NodeSeq = {
nodeList.flatMap {node => Helpers.bind("node", html, "name"->node.name, "data"->node.data) }
}
现在问题:
如何绑定而不在html中指定我希望html代码调用哪个方法。我的意思是我想删除这一行:<div class="lift:helloWorld.displayNodes">
因为我不希望在填充列表之前调用它。所以基本上代替html“调用”scala代码我希望scala代码调用html并绑定到它,但只有在它有数据之后。怎么办呢?
PS - 我看了cookbook.liftweb.net,但他们没有我需要的例子。
答案 0 :(得分:1)
我不确定你是如何设置系统的,但通常对于服务器推送你想要使用Comet actor。下面的代码应该让您在该路径上开始,因为它将执行初始渲染,然后允许您根据消息事件向页面发送部分更新。因此,在这种情况下,它将响应加载列表时应发送的事件pushList
。您可以阅读有关演员here的更多信息。
HTML文件
<div data-lift="comet?type=HelloWorldActor">
<span id="nodes"></span>
</div>
<强>演员强>
case class HelloWorldActor() extends CometActor {
//Handle any messages received
override def lowPriority: PartialFunction[Any, Unit] = {
case "pushList" =>
partialUpdate {
JsCmds.SetHtml("nodes", displayNodes.apply(listTemplate))
}
}
//Look up the template from templates-hidden/list.html or if that does not exist
//use the default NodeSeq specified
def listTemplate = Templates.apply("templates-hidden" :: "list" :: Nil) openOr
<div>
<div><li><B>Node:</B></li></div>
<div>Name: <span name="name"></span></div>
<div>Data: <span name="data"></span></div>
<BR>
</div>
//Load the list, and then on completion send the actor the message to push the list
//This could also happen from outside the actor, you'd send the message in a similar
//fashion from wherever it happens
def loadList() = {
//load the data in your list and on complete
this ! "pushList"
}
//The CSS Selector to output the node
def displayNodes = {
"*" #> nodeList.map { node =>
"@name" #> node.name &
"@data" #> node.data
}
}
//Initial CSS Transformation
override def render = {
//Your initial CSS transformation
}
}
您将看到JsCmds.SetHtml
是实际在页面上设置HTML的内容。它只是一个JavaScript命令,用于在html元素上查找给定的id,然后将其替换为指定的NodeSeq
。如果您不想使用Comet,可以使用该命令作为任何返回JsCmd
的Lift组件的响应。
我还提取了输出节点的HTML,以便于说明。 Templates
对象包含一个使用设计器友好模板的机制,可以查找和重复使用,这样你就不会丢失任何东西。但是,如果您想在一个文件中继续使用HTML,则可以捕获初始render
中的元素:"#nodes" #> { ns => listTemplate = ns; PassThru }
(将listTemplate
更改为{{1}后当然)。
答案 1 :(得分:1)
我建议使用SHtml.idMemoize
http://lift.la/blog/shtmlidmemoize-simple-ajax-updating
这样,您最初可以拥有一个输入页面,但没有结果。在用户输入数据并且服务器获取数据库数据后,您可以通过查询outer.setHtml
它比设置CometActor
更便宜,更容易,但只有当用户提出要求时才会得到结果。因此,这样服务器就无法自行将某些更新推送到浏览器。