Binding 在Lift中将Scala绑定到HTML
我已经开始玩升降机了。我想创建一个基本应用程序,它通过输入字段从用户处获取输入,对该输入执行db搜索,并获取db搜索的结果,创建一个对象列表,然后绑定到一些html代码 我只需要关于绑定部分的帮助,但首先需要一些背景信息 我有一个列表[节点]:Binding 在Lift中将Scala绑定到HTML,binding,lift,Binding,Lift,我已经开始玩升降机了。我想创建一个基本应用程序,它通过输入字段从用户处获取输入,对该输入执行db搜索,并获取db搜索的结果,创建一个对象列表,然后绑定到一些html代码 我只需要关于绑定部分的帮助,但首先需要一些背景信息 我有一个列表[节点]: case类节点(aname:String,adata:String){..} 我要将此html绑定到: <div class="lift:helloWorld.displayNodes"> <div>
case类节点(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>
现在问题是:如何绑定而不在html中指定希望html代码调用的方法。我的意思是我想删除这一行:
,因为我不想在填充列表之前调用它。因此,基本上,我希望scala代码调用html并绑定到它,而不是html“调用”scala代码,但只有在它拥有数据之后。如何做到这一点
PS-我查看了cookbook.liftweb.net,但他们没有我需要的示例。我不确定您的系统是如何设置的,但通常对于服务器推送,您希望使用Comet actor。下面的代码应该让您开始使用该路径,因为它将执行初始渲染,然后允许您根据消息事件向页面发送部分更新。因此,在这种情况下,它将响应加载列表时应发送的事件
pushList
。你可以阅读更多关于演员的内容
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
}
}
case类HelloWorldActor()扩展了CometActor{
//处理收到的任何消息
覆盖def低优先级:部分功能[任何,单元]={
案例“推送列表”=>
部分更新{
JsCmds.SetHtml(“节点”,displayNodes.apply(listTemplate))
}
}
//从templates hidden/list.html中查找模板,或者如果该模板不存在的话
//使用指定的默认NodeSeq
def listmetplate=Templates.apply(“隐藏的模板”::“列表”::Nil)openOr
节点:
姓名:
数据:
//加载列表,然后在完成时向参与者发送消息以推送列表
//这也可能发生在演员之外,你可以用类似的方式发送信息
//来自任何地方的时尚
def loadList()={
//在列表中加载数据,并在完成时加载
这是“推送名单”
}
//用于输出节点的CSS选择器
def displayNodes={
“*”#>nodeList.map{node=>
“@name”#>node.name&
“@data”#>node.data
}
}
//初始CSS转换
覆盖def呈现={
//您最初的CSS转换
}
}
您将看到是什么实际设置了页面上的HTML。它只是一个JavaScript命令,在html元素上查找给定的id,然后用指定的NodeSeq
替换它。如果您不打算使用Comet,可以使用该命令作为任何返回JsCmd
的提升组件的响应
我还提取了输出节点的HTML,以便于说明。
Templates
对象包含一种使用设计器友好模板的机制,该模板可以被查找并重复使用,这样做就不会丢失任何东西。但是,如果您想继续在一个文件中使用HTML,您可以在初始的呈现中捕获元素,比如:“#节点”#>{ns=>listmlate=ns;PassThru}
(当然,在将listmlate
更改为var
之后)。我建议使用SHtml.idmemorize
通过这种方式,您最初可以拥有一个带有输入但没有结果的页面。在用户输入数据并且服务器得到数据库数据后,您可以通过查询outer.setHtml
这比设置一个CometActor
更便宜、更容易,但只有当用户提出要求时,才能得到结果。因此,这样服务器将无法自行将某些更新推送到浏览器。JsCmds.SetHtml链接非常棒!我要用记忆或接线
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
}
}