PlayFramework 中的@helper.repeat

@helper.repeat in PlayFramework

我不明白怎么描述@helper.repeat in play2.2.1.

@helper.form(action = routes.Application.send) {

    @helper.repeat(
        field = form1("input"), min = 3
    ) {fld =>
        @helper.inputText(
            field = fld, '_label ->"input"
        )
    }
}

fld => @helper.inputText(field = fld)部分我看不懂。 这是什么意思? 我知道Java,所以我认为它是函数式写法,但是在上面的代码中,变量fld是从哪里来的呢? 为什么箭头的尖端指示@helper.inputText(field = fld)? 为什么 fld 字段的值是 @helper.inputText? 我用谷歌搜索过,但找不到对初学者足够的解释。 我不确定 Scala 的语法。 请为初学者解释以上代码?

原答案

这似乎有点过于复杂了。无需手动赋值。通常你会像这样写一个转发器:

@helper.repeat(form1("input"), min = 3) { fld =>
  @helper.inputText(fld, '_label ->"input")
}

在函数式编程中,这就是所谓的 higher-order function。您可能知道其他内置高阶函数的 Scala,例如 mapfilterforeach@helper.repeatforeach 非常相似。 form1("input") 指的是要显示的值的集合。 min = 1 告诉中继器至少显示一个字段。最后,在 { fld => ... } 中,您遍历了集合中定义的所有值。

换句话说:{ fld => ... } 只是一个匿名函数,它采用单个 Field 参数 (fld) 并显示该特定字段的文本输入。

跟进

好的,我正在尝试从评论中跟进您的问题。让我们从helper.repeat的签名开始。这里没有魔法,它只是一个普通的 Scala 函数:

helper.repeat(field: Field, min: Int)(fieldRenderer: (fld: Field) => Html): Seq[Html]

在 Scala 中,函数可以有多个参数列表。这里我们有两个。第一个参数列表有两个参数:fieldmin。第二个参数列表将单个函数作为参数:fieldRendererfieldRenderer 本身再次采用单个参数 (fld) 和 returns Html.

重要的是,您传递的不是 "data" 而是一个函数。要清除此问题:

签名fieldRenderer: (fld: Field) => Html

等于def fieldRenderer(fld: Field): Html

这意味着,您可以在此函数内执行任何操作,只要它 returns Html。这正是顶部示例中发生的情况。你传递了一个 Field 和 return Html。您可以通过调用 @helper.inputText.

来做到这一点

现在 repeat 首先从作为第一个参数传递的 field 中获取 List[Field]。此列表对应于您的容器 class 的字符串列表。此外 repeat 确保该列表中至少有一个元素。这是因为您将 1 传递为 min。然后函数 fieldRenderer 应用于我们列表中的所有元素。

repeat 的伪代码实现可能如下所示:

def repeat(field: Field, min: Int)(fieldRenderer: (fld: Field) => Html): Seq[Html] {
  val list: List[Field] = field.getFields

  var output: List[Html] = List()
  for (i = 0; i < list.length; i++) {
    val element: Field = list.get(i)
    val html: Html = fieldRenderer(element)
    output += html
  }

  return output
}