2

我正在构建一个 Lift 应用程序,其中一个页面基于 Lift 演示中的“文件上传”示例,网址为:http: //demo.liftweb.net/file_upload

如果您查看该页面的源代码......您会看到有一个 Lift“snippet”标签,围绕着两个“choose”标签:

<lift:snippet type="misc:upload" form="post" multipart="true">

<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
</choose:post>

<choose:get>
Select a file to upload: <ul:file_upload></ul:file_upload><br >
<input type="submit" value="Upload File">
</choose:get>

</lift:snippet>

这个想法是,当用户第一次点击页面(即 GET 请求)时,Lift 将显示用于上传文件的表单。当用户提交表单(即对同一页面的 POST 请求)时,Lift 会显示正在处理的文件的结果。

对于我的应用程序,新的问题是我的“结果”POST 视图需要包含一个表单。我想为用户提供一个文本输入以输入电子邮件地址,以及一个提交按钮,按下该按钮将通过电子邮件发送有关已处理文件的信息:

...
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>

<!-- BEGIN NEW STUFF -->
Output: <br/>
<textarea rows="30" cols="100"><ul:output></ul:output></textarea>
<br/><br/>
Email the above output to this email address:<br/>
<ul:email/><br/>
<input type="submit" value="Email"/>
<!-- END NEW STUFF -->

</choose:post>
...

但是,此页面的 GET 和 POST 版本都由同一个 Lift 生成的表单包装,在这两种情况下,它的“操作”设置为相同的代码段。如何更改此设置,以便在 POST 版本中,表单的操作更改为不同的代码段?

在一个典型的 Web 框架中,我会使用“onclick”事件和两行基本的 JavaScript 来处理这样的事情。然而,我什至还没有开始思考 Lift 的……呃,关于在 Scala 中编写 JavaScript 的有趣概念。也许我需要走那条路,或者也许有更好的方法。

4

3 回答 3

2

首先,我建议您使用 Lift 的新设计友好 CSS 绑定而不是自定义 XHTML 标记。

当您使用 Lift 的代码片段时,您应该记住的一件事是它是递归的,您可以将提升代码片段放在另一个代码片段的 HTML 块中。

例如,如果您希望在 POST 之后有另一个表单,那么只需将其放入块中。

<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
<!-- 
    The following is same as <lift:snippet type="EMailForm" form="post" multipart="true"> 
-->
<form action="" method="post" data-lift="EMailForm">
    <input type="text" name="email"/>
    <input type="submit" />
</form>
</choose:post>

然后处理片段类 EMailForm 中的电子邮件表单操作。

最后,您可以使用隐藏的表单元素或 SessionVar 传递文件名/矿工类型和其他信息。

于 2012-06-09T16:50:38.770 回答
1

我同意 Brian 的观点,使用 Lift 的新设计师友好的 CSS 绑定。

使用两种单独的表格,一种用于文件上传,另一种用于提交电子邮件。当第一个表单完成处理后,使用 S.seeOther 将用户重定向到第二个表单。

我也更喜欢新的 'data-lift' HTML 属性。

文件上传 HTML:

<div data-lift="uploadSnippet?form=post">
    <input type="file" id="filename" />
    <input type="submit" id="submit" />
</div

文件上传片段:

class uploadSnippet {
    def processUpload = {
        // do your processing
        ....
        if (success)
            S.seeOther("/getemail")

        // if processing fails, just allow this method to exit to re-render your 
        // file upload form
    }

    def render = {
        "#filename" #> SHtml.fileUpload(...) &
        "#submit" #> SHtml.submit("Upload", processUpload _ )
    }
}

获取电子邮件 HTML:

<div data-lift="getEmailSnippet?form=post">
    <input type="text" id="email" />
    <input type="submit" id="submit" />
</div

获取电子邮件片段:

class getEmailSnippet {
    def processSubmit = {
       ....
    }

    def render = {
        "#email" #> SHtml.text(...) &
        "#submit" #> SHtml.submit("Upload", processSubmit _ )
    }

在我关于使用 RequestVar 的博客文章中有更多关于表单处理的内容:http: //tech.damianhelme.com/understanding-lifts-requestvars

如果您想要更多详细信息,请告诉我。

希望这有用

干杯

达米安

于 2012-06-10T10:40:00.710 回答
0

如果有人在接下来的几天内提出更优雅(或“Lift-y”)的方法,那么我会接受他们的回答。但是,我自己想出了一个解决方法。

我保留了当前布局,其中视图有一个 GET 块和一个 POST 块都提交到相同的片段函数。片段函数仍然有一个if-else块,根据它是 GET 还是 POST 以不同方式处理每个请求。

但是,现在我在 POSTif-else内也有一个辅助块。此内部if-else查看单击的提交按钮的名称。如果提交按钮是用于上传文件的按钮,那么代码片段将处理文件的上传和处理。否则,如果它是在第一个 POST 之后显示的发送电子邮件提交按钮,则代码段会处理电子邮件的发送。

不是特别迷人,但效果很好。

于 2012-06-08T20:22:33.053 回答