【问题标题】:Why can I not mix Scala code with HTML here in Play Framework 2 views?为什么我不能在 Play Framework 2 视图中将 Scala 代码与 HTML 混合?
【发布时间】:2014-02-09 10:36:29
【问题描述】:

我制作了一个示例,它应该读取 JSON 文件并在 Play Framework 2.2 的常规视图中将其数据显示为 HTML。

视图如下所示:

@(json: play.api.libs.json.JsValue)

@import play.api.libs.json._

@main("JSON Read") {

    <h1>JSON Read</h1>

    <p>This sample reads a JSON file containing some book categories and a few books inside these categories.</p>
    <!-- THIS WORKS -->
    <p>This link demonstrates a route with parameter: <a href="@routes.JsonSamples.bookdetails("12345678")">Link to book 12345678</a></p>

    @json.as[List[JsObject]].map { section =>
        <table>
            <caption>
                <h2>@{(section \ "title").as[String]}</h2>
                <p>@{(section \ "description").as[String]}</p>
            </caption>
            <thead>
                <tr>
                    <th>Book Title</th>
                    <th>Description</th>
                </tr>
            </thead>
            <tbody>
        @{(section \ "entries").as[List[JsObject]].map { entry =>
                <tr>
                    <td>
                        <!-- By the way... I can't even use @* *@ comments here. Why? -->

                        <!-- I DON'T KNOW WHAT TO PUT INTO HREF, NOTHING WORKS, SEE BELOW -->
                        <a href="#">
                            {(entry \ "title").as[String]}
                        </a>

                        <!-- THIS WORKS -->
                        (ID: {(entry \ "id").as[String]})
                    </td>
                    <td>
                        <p>{(entry \ "description").as[String]}</p>
                        <p>Order link: {(entry \ "link").as[String]}</p>
                    </td>
                </tr>
        }}
            </tbody>
        </table>
    }

}

在中间的某个地方,您可以看到我尝试为每本书插入一个生成的链接,但我根本无法在&lt;a&gt; 标记的href="" 属性内打印任何内容。我试过了:

Attempt 1:
<a href="@routes.JsonSamples.bookdetails((entry \ "id").as[String])">
...Compilation error: unclosed multi-line string literal

Attempt 2:
<a href="@(routes.JsonSamples.bookdetails((entry \ "id").as[String]))">
...Compilation error: in XML literal: whitespace expected

Attempt 3:
<a href="@{routes.JsonSamples.bookdetails((entry \ "id").as[String])}">
...Compilation error: in XML literal: whitespace expected

Attempt 4:
<a href="{routes.JsonSamples.bookdetails((entry \ "id").as[String])}">
...Compilation error: in XML literal: whitespace expected

有时您可以简单地使用@ 符号来显示数据。

有时你必须使用@ {}包装代码(即@{…})。

有时甚至不允许使用@,您只能使用{}

有时这些方法都不起作用。

很明显,它必须与代码是否在另一个代码块内有关。但是(可能在大多数情况下)一切都被包装到 @main {…} 中并且它可以工作,但是你包装的代码块越多似乎越难以显示值。

所以,主要的具体问题是:如何在上面显示当前仅显示 href="#" 的链接/路由?

更普遍的问题是:是否有一种清晰易懂的方式将代码与 HTML 混合?

JSON 文件:https://github.com/Manc/play-samples/blob/json/data/books.json

控制器:https://github.com/Manc/play-samples/blob/json/app/controllers/JsonSamples.scala

观点:https://github.com/Manc/play-samples/blob/json/app/views/jsonsamples/read.scala.html

我还注意到,即使是 @* *@ 评论块也不允许在视图中的任何地方出现。

我来自 PHP,它总是非常清楚什么是 PHP 代码,什么不是。甚至,例如Laravel(一个 PHP 框架)模板引擎 Blade 使用类似的方法,您可以在代码中混合使用 @ 符号或 {{ … }} 以打印变量/函数/方法的值或 @ 987654339@ 做同样的事情,但 HTML 安全转义。

【问题讨论】:

    标签: scala playframework playframework-2.2


    【解决方案1】:

    首先快速修复

    @for(entry <- (section \ "entries").as[List[JsObject]]) {
      <tr>
        <td>
          <a href="@routes.JsonSamples.bookdetails((entry \ "id").as[String])">
            @{(entry \ "title").as[String]}
          </a>
        </td>
        <td>
          <p>@{(entry \ "description").as[String]}</p>
          <p>Order link: @{(entry \ "link").as[String]}</p>
        </td>
      </tr>
    }
    

    您的代码的问题是使用了@{...}。问题是,该块内的所有内容都被视为 scala 代码。这就是@**@ cmets 不起作用的原因,它们不是有效的 scala 语法。 Scala 有 xml 文字,允许在里面包含 html 标签。

    这意味着我们需要摆脱循环内部的 scala 语法。问题是,我找不到一种方法来做到这一点并保留地图语法。因为@(section \ "entries").as[List[JsObject]].map { entry =&gt; 中的section \ "entries" 周围有括号,所以模板引擎只将那部分视为scala 代码。要解决这个问题,您可以使用 for 的替代语法。

    所以对于简单的表达式使用@。使用@{...} 不是那么简单的表达式,但请记住,块内的所有内容都是scala 代码(所以没有更多@)。不能使用@ 的地方在scala 代码中。

    当简单的表达式不够用时,这可能会导致问题,你需要做一个map 或其他东西,但总是有defining 帮助器,你不应该在模板中做太复杂的事情。

    【讨论】:

    • 非常感谢您的出色解释。它与您更改代码的方式完全一样。我希望我会习惯这种语法。 :)
    猜你喜欢
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 2016-11-30
    • 2014-12-26
    相关资源
    最近更新 更多