将参数化URL添加到Lift应用程序

时间:2015-02-18 19:00:27

标签: parameters url-routing lift

我需要参数化网址的最基本情况:使用类似localhost:8080/editStudy/4的网址,这将导致用于编辑ID等于4的研究的表单。

但即使经历了Lift Wiki和我拥有的书籍,我也没有找到如何做到这一点。到目前为止我所拥有的是一个HTML页面editStudy.html,它将来会包含编辑表单,一个应该呈现表单的类StudyDisplayer,一个定义某个东西的对象StudyDisplayer像菜单(它是ParamMenuable,不管这是什么),以及站点地图中的条目。

转到localhost:8080/editStudy/4

  

在此服务器上找不到请求的URL / editStudy / 4

尽管站点地图中引用了该位置。我做错了什么?在访问URL时,我在哪里告诉Lift显示editStudy页面?


editStudy.html:

<html>
  <head>
    <title></title>
    <meta content="">
        <link rel="stylesheet" type="text/css" href="litsuche.css">
  </head>
  <body>
    <nav>
      <span data-lift="Menu.builder"></span>
    </nav>
    <div data-lift="StudyDisplayer">
        <h1>Editing the study <span id="reference"></span></h1>
    </div>
  </body>
</html>

StudyDisplayer:

package code
package snippet

import org.rumtscho.litsuche._
import net.liftweb.util.BindHelpers._
import xml.Text

import net.liftweb.sitemap._

object StudyDisplayer {

  def showStudies = {
    val theStudies = Study.findAll

    "li *" #> theStudies.map {
      s =>
        ".id *" #> Text(s.id.toString) &
        ".handmadeRef *" #> Text(s.reference) & 
        ".description *" #> Text(s.description) & 
        ".editStudyButton" #> <button class="editStudyButton" onclick={"location.href='" + editStudyLoc.calcHref(s) + "'"}>edit</button>
    }
  }


    val editStudyLoc = Menu.param[Study](
        "EditStudy", 
        "editStudy", //This is supposed to be some kind of link, but it doesn't work with the name of the file, with or without a .html ending. The file itself is in the root directory. 
        Study.findByIdAsString(_),
        _.id.toString()
        ) / "editStudy" / *
}

class StudyDisplayer(study: Study) {
  def render = "#reference *" #> study.reference
}

以及Boot.scala的相关摘录:

def sitemap(): SiteMap = SiteMap(
  Menu.i("Home") / "index",
  Menu.i("List studies") / "studies", 
  Menu(StudyDisplayer.editStudyLoc),
  Menu.i("Temporary page") / "scratchpad")

LiftRules.setSiteMap(sitemap())

1 个答案:

答案 0 :(得分:3)

Lift有两种添加参数的机制。 Menu.paramMenu.params。它们之间的区别在于所需的参数数量。

Menu.param假设一个参数,所以在你的情况下你有:

Menu.param[Study](
    "EditStudy", 
    "editStudy", 
    Study.findByIdAsString(_),
    _.id.toString()
) / "editStudy" 

这是最简单的机制,因为它会查找名为“editStudy.html”的模板,并采用它假定存在的一个参数并将其传递给您的函数:Study.findIdAsString。如果函数返回Full,则未装箱的值将传递到您的代码段进行渲染。如果函数返回Empty Lift将默认返回404。

Menu.Params或多或少相同,但它允许您指定多个参数和/或匹配多个URL。例如,我们可以将您的示例调整为:

Menu.params[Study]("EditStudy", "EditStudy", {
    case s :: Nil => Study.findByIdAsString(s)
    case _ => Empty
}, {
    case g = > g.id :: Nil
}) / "editStudy" / *

你会注意到我们在“editStudy”之后有一个通配符匹配。原因是没有关于参数数量的假设,因此如果要查找单个参数或*将每个子路径与“editStudy”匹配,则需要指定**查找的内容。对于您想要查找的每个模式,您只需在匹配中添加一个新的case语句。

如果您想要返回多个项目,甚至可以使用元组键入Menu.params,例如:

Menu.param[(Study, Grade)]("EditStudy", "EditStudy", {
    case s :: g :: Nil => (Study.findByIdAsString(s), Grade.findByIdAsString(g))
    case _ => Empty
}, {
    case (g, s) => g.id :: s.id :: Nil
}) / "editStudy" / **

哪个会在网址中查找两个id参数,例如:“/ editStudy / 1234/5678”

另请注意,在处理模式匹配时,使用提取器来检索值通常更简洁。如果您需要,This article会有更多信息。