包含局部变量的Play/Scala模板块语句HTML输出语法 [英] Play/Scala Template Block Statement HTML Output Syntax with Local Variable

查看:93
本文介绍了包含局部变量的Play/Scala模板块语句HTML输出语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我已经为此苦苦挣扎了一段时间,并花了很多时间尝试做不同的事情来做一些我很容易使用PHP完成的事情.

Ok, I've been stuggling with this one for a while, and have spent a lot of time trying different things to do something that I have done very easily using PHP.

我试图遍历列表,同时在本地跟踪变量,同时吐出HTML尝试填充表.

I am trying to iterate over a list while keeping track of a variable locally, while spitting out HTML attempting to populate a table.

尝试#1:

@{
    var curDate : Date = null
    for(ind <- indicators){
        if(curDate == null || !curDate.equals(ind.getFirstFound())){
            curDate = ind.getFirstFound()
            <tr><th colspan='5' class='day'>@(ind.getFirstFound())</th></tr>
            <tr><th>Document ID</th><th>Value</th><th>Owner</th><th>Document Title / Comment</th></tr>
        }
    }
}

我也尝试使用scala block语句,以允许我将curDate保留为创建范围内的变量.该块正确地保持curDate状态,但不允许我向DOM输出任何内容.由于我未转义,随机抛出HTML,因此我实际上并没有期望它能够编译,但是它确实可以编译.尽管决策结构已在服务器上正确执行,但此循环只是在DOM上不放置任何内容.

I attempt too user a scala block statement to allow me to keep curDate as a variable within the created scope. This block correctly maintains curDate state, but does not allow me to output anything to the DOM. I did not actually expect this to compile, due to my unescaped, randomly thrown in HTML, but it does. this loop simply places nothing on the DOM, although the decision structure is correctly executed on the server.

我尝试使用@Html('...')进行转义,但这产生了编译错误.

I tried escaping using @Html('...'), but that produced compile errors.

尝试#2:

很多Google搜索使我进入了理解范围":

A lot of google searches led me to the "for comprehension":

@for(ind <- indicators; curDate = ind.getFirstFound()){
    @if(curDate == null || !curDate.equals(ind.getFirstFound())){
        @(curDate = ind.getFirstFound())
    }
    <tr><th colspan='5' class='day'>@(ind.getFirstFound())</th></tr>
    <tr><th>Document ID</th><th>Value</th><th>Owner</th><th>Document Title / Comment</th></tr>
}

在此块中没有if语句,这是我实际上要执行的最接近的操作,但是显然我不允许重新分配非引用类型,这就是为什么我希望尝试#1的引用声明curDate : Date = null可以工作.这种尝试使我获得了页面上的HTML(同样,如果我删除了嵌套的if语句),但没有得到

Without the if statement in this block, this is the closest I got to doing what I actually wanted, but apparently I am not allowed to reassign a non-reference type, which is why I was hoping attempt #1's reference declaration of curDate : Date = null would work. This attempt gets me the HTML on the page (again, if i remove the nested if statement) but doesn't get me the

我的问题是,我应如何实现这一意图?我非常痛苦地意识到我缺乏Scala知识,而Play模板语法正在加剧这种情况.我不确定该怎么办.

My question is, how do i implement this intention? I am very painfully aware of my lack of Scala knowledge, which is being exacerbated by Play templating syntax. I am not sure what to do.

提前谢谢!

推荐答案

Play的模板语言非常适合函数式编程.可以使用可变状态来实现您想要实现的目标,但是最好是顺其自然,并使用功能性解决方案.

Play's template language is very geared towards functional programming. It might be possible to achieve what you want to achieve using mutable state, but you'll probably be best going with the flow, and using a functional solution.

如果要在函数式编程中的循环迭代之间保持状态,可以通过折叠来完成-从某种状态开始,在每次迭代中,获得上一个状态和下一个元素,然后然后根据这两件事返回新状态.

If you want to maintain state between iterations of a loop in functional programming, that can be done by doing a fold - you start with some state, and on each iteration, you get the previous state and the next element, and you then return the new state based on those two things.

因此,看看您的第一个解决方案,您似乎想做的就是仅在日期与前一个日期不同时才打印一个元素,对吗?另一种放置方法是,您要过滤出所有日期与上一个日期相同的元素.用折叠表示,我们将元素折叠成一个序列(我们的初始状态),如果折叠序列的最后一个元素的日期与当前日期不同,则将其添加,否则忽略它.

So, looking at your first solution, it looks like what you're trying to do is only print an element out if it's date is different from the previous one, is that correct? Another way of putting this is you want to filter out all the elements that have a date that's the same date as the previous one. Expressing that in terms of a fold, we're going to fold the elements into a sequence (our initial state), and if the last element of the folded sequence has a different date to the current one, we add it, otherwise we ignore it.

我们的褶皱看起来像这样:

Our fold looks like this:

indicators.foldLeft(Vector.empty[Indicator]) { (collected, next) =>
  if (collected.lastOption.forall(_.getFirstFound != next.getFirstFound)) {
    collected :+ next
  } else {
    collected
  }
}

仅解释上述内容,我们将其折叠为Vector,因为Vector具有固定时间追加,最后,List具有n时间.如果collected中没有最后一个元素,则forall将返回true,否则,如果传入的lambda计算为true,则它将返回true.在Scala中,==调用.equals(在执行空检查之后),因此您无需在Scala中使用.equals.

Just to explain the above, we're folding into a Vector because Vector has constant time append and last, List has n time. The forall will return true if there is no last element in collected, otherwise if there is, it will return true if the passed in lambda evaluates to true. And in Scala, == invokes .equals (after doing a null check), so you don't need to use .equals in Scala.

因此,将其放在模板中:

So, putting this in a template:

@for(ind <- indicators.foldLeft(Vector.empty[Indicator]) { (collected, next) =>
  if (collected.lastOption.forall(_.getFirstFound != next.getFirstFound)) {
    collected :+ next
  } else {
    collected
  }
}){
  ...
}

这篇关于包含局部变量的Play/Scala模板块语句HTML输出语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆