【问题标题】:Declare variable in a Play2 scala template在 Play2 Scala 模板中声明变量
【发布时间】:2012-08-15 09:34:12
【问题描述】:

如何在 Play2 Scala 模板中声明和初始化要在本地使用的变量?

我有这个:

@var title : String = "Home"

在模板顶部声明,但它给了我这个错误:

illegal start of simple expression """),_display_(Seq[Any](/*3.2*/var)),format.raw/*3.5*/(""" title : String = "Home"

【问题讨论】:

    标签: html scala templates playframework playframework-2.0


    【解决方案1】:
    @defining("foo") { title=>
      <div>@title</div>
      ...
    }
    

    基本上,您必须将要使用它的块包装起来

    【讨论】:

    • “foo”是什么意思?不是单词本身,而是这个参数在哪里使用?
    • "foo" 是要计算的表达式。您可以使用元组执行诸如 "@defining( (1,2,3) ) { case(a,b,c)=> ... }" 之类的事情,并传入您喜欢的任何 scala 表达式。有效,但与在正常的 scala 代码中定义 val 相比,这是一种痛苦
    • @virtualeyes 纠正我,如果我错了,但这将定义一个值,而不是一个变量,当你尝试在模板中进一步修改它时,你会得到编译错误。
    • @AlexanderArendar 是的,播放模板是不可变的,没有办法改变任何东西的状态(即除非你从其他地方拉入可变状态)
    • "foo" 是参数。标题获取字符串“foo”值。您也可以使用列表或任何其他类型作为参数。
    【解决方案2】:

    实际上,@c4k 的解决方案是有效的(而且非常方便),只要您事后不尝试更改变量的值,不是吗?

    您只需将其放在模板的顶部即可:

    @yourVariable = {yourValue}
    

    或者,如果它是一个更复杂的表达式,你可以这样做:

    @yourVariable = @{yourExpression}
    

    您甚至可以使用类似列表之类的东西:

    @(listFromController: List[MyObject])
    @filteredList = @{listFromController.filter(_.color == "red")}
    
    @for(myObject <- filteredList){ ... }
    

    对于给定的示例,这将是

    @title = {Home}  //this should be at beginning of the template, right after passing in parameters
    
    <h1> Using title @title </h1>
    

    在您所说的 cmets 中,它被键入为 HTML 类型。但是,只有当您再次尝试覆盖 @title 时,这才是相关的,不是吗?

    【讨论】:

    • 显然它在@for 中不起作用。但是,它不需要一直位于文件的顶部。
    • 谢谢!!!使用它而不是 @defining 感觉很棒。 @defining 指令根本不可读
    • 这在哪里记录了您可以使用花括号分配一个变量?
    【解决方案3】:

    scala模板支持这个,你可以在模板中定义变量

    @import java.math.BigInteger; var i=1; var k=1
    

    如果你想在模板中改变它的值

    @{k=2}
    

    例子

    @(title:String)(implicit session:play.api.mvc.Session)
    @import java.math.BigInteger; var i=1; var k=1
    ^
    <div id='LContent_div@i'>
                         ^
      <div id='inner_div_@k'></div>
                         ^
    </div>
    

    【讨论】:

    • 它并不适合我。你能提供一个最小的示例模板来展示如何正确使用它吗?
    • 感谢 Govin Singh,我可以声明一个变量并在 html 代码中使用它。但我不明白它是如何工作的,为什么要导入 java.math.BigInteger?
    • @GovindSinghNagarkoti,感谢您的更新。没有 import 子句能用吗?
    • @AlexanderArendar noops!
    • @GovindSinghNagarkoti 好的,那是一个有趣的案例。感谢您提供信息。
    【解决方案4】:

    virtualeyes 的解决方案是正确的,但还有其他可能性,您可以像通常使用默认值一样声明视图的参数,在这种情况下,您可以将其用于整个模板 + 您将保留以下可能性从controller 更改它:

    @(title: String = "Home page")
    
    <h1>Welcome on @title</h1>
    

    控制器:

    def index = Action{
        Ok(views.html.index("Other title"))
    }
    

    注意Java控制器不识别模板的默认值,所以每次都需要添加:

    public static Result index(){
        return ok(views.html.index.render("Some default value..."));
    }
    

    【讨论】:

    • 嘿,感谢您的替代方案,但我不想将其声明为参数...我只是希望它是一个直接的基本变量,我可以在本地模板中访问,即不被继承。有没有直接的替代方案?
    • @virtualeyes virtualeyes 展示了使用@defining("foo") 的方法,只有两种可能的方法。第三种选择不存在。
    • 真的吗?那么@defining 是在 Play2 模板中声明私有实例变量的唯一方法吗?那是相当短视的......无论如何谢谢你的意见。
    • 真的,正如我在某处写的那样——我找不到任何好的理由在模板中声明变量并稍后使用它们,因为它将指向静态数据并且没有意义(恕我直言)。 Controller 应该关心定义变量 - 这意味着,view/template 应该只关心显示它们。
    • 多模块界面框架...每个最低级别的子模板都需要一个...我知道您还没有满足对一个的需求,但这并不意味着没有一个。无论如何@defining 会再次为您的输入做 thx。
    【解决方案5】:

    如果你不想用@defining 包装你的所有内容,你可以这样做:

    @yourVariable = { yourValue }
    

    @defining 指令在模板中确实不可读...

    【讨论】:

    • 这会将你的变量变成一个 html 的东西
    • 精确,这并不能解决问题。我在我的模板中尝试过,然后这样声明的“变量”被输入到 HTML 类型。
    【解决方案6】:

    有一个明显的解决方案,看起来很干净,有时可能更受欢迎:在模板周围定义一个范围,在其中定义你的变量,然后让范围生成你需要的 html 代码,如下所示:

    @{
      val title = "Home"
    
      <h1>Welcome on {title}</h1>
    }
    

    这有一些缺点:

    • 您正在以这种方式将 html 生成为 Scala NodeSeq,这有时可能会受到限制
    • 此解决方案存在性能问题:@{ 内部的代码似乎是在运行时编译的,因为为页面生成的 Scala 代码如下所示(删除了一些常见的 Twirl 内容):

    生成的代码:

    ...    
    
    Seq[Any](format.raw/*1.1*/("""<!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Basic Twirl</title>
        </head>
        <body>
    
            """),_display_(/*9.10*/{
                val title = "Home"
    
                    <h1>Welcome on {title}</h1>
            }),format.raw/*15.10*/("""
    
        """),format.raw/*17.5*/("""</body>
    </html>"""))
          }
        }
      }
    
    ...
    

    【讨论】:

      【解决方案7】:

      在旋转模板中,我建议使用定义块,因为

      @random = @{
           new Random().nextInt
      }
      
      <div id="@random"></div>
      <div id="@random"></div>
      

      多次使用会产生不同的值!

      @defining(new Random().nextInt){ random =>
          <div id="@random"></div>
          <div id="@random"></div>
      }
      

      【讨论】:

        【解决方案8】:

        对于任何尝试Govind Singh答案的人:
        我不得不将带有变量 的导入行放在参数列表下,即

        @(title:String)(implicit session:play.api.mvc.Session)
        @import java.math.BigInteger; var i=1; var k=1
        

        有效。

        但是将带有变量的导入放在导入语句上,即

        @import java.math.BigInteger; var i=1; var k=1
        @(title:String)(implicit session:play.api.mvc.Session)
        

        对我不起作用并导致错误:

        expected class or object definition
        

        【讨论】:

          【解决方案9】:
          @isExcel= {@Boolean.valueOf(java.lang.System.getProperty(SettingsProperties.isExcel))}
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-10-17
            • 2016-04-15
            • 1970-01-01
            • 1970-01-01
            • 2019-08-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多