我观察到,当我增加超过18个参数的游戏框架表级我弄了半天(对我来说难以理解)编译错误。
这是一个记录的限制吗? 我需要在多达29参数窗体发布。 因为我从实施的开放标准的协议,我不上的参数设计和数量决定。
我这样的映射:
val registration = Form(mapping(
"client_type" -> nonEmptyText,
"client_id" -> optional(nonEmptyText),
... up to 29 args, all optional(nonEmptyText)
){ (clientType, clientId ...) => RegistrationRequest(clientType, clientId ...) }
{ req => None })
我的策略是做映射这种方式,而不是申请/取消应用,创造case类的层次结构。 原因是解决了22个论点限制在个案班,这是我遇到的第一个看似随意的限制。 多达18个ARGS测绘工作,在那之后我得到很长的编译错误。
可以在这里找到该错误消息(太长包括): https://gist.github.com/2928297
我在寻找的建议我如何能解决此限制得到。 我知道这是不好的设计在29个参数发送的形式发布,但应该还是可以的。
哈克/变通方法/解决方案
好吧,这里是我砍死在一起的解决方法(写这篇文章花了更长的时间比实现,我砍死了〜30分钟就这一点)
我写了预处理的请求参数,并增加了一组前缀组一定PARAMS功能。 然后我使用生成的地图[字符串,字符串]并继续处理与表单类,做验证等如常。 这让我在映射使用嵌套case类,并得到低于18个PARAMS限制。
当心:丑陋的代码迈进! 我可能不应该表现出早期哈克这样的代码,但我希望它会帮助别人谁想要一个解决方法。
def preprocessFormParams(prefix:String, replace:String)(implicit request:Request[AnyContent]):Map[String, String] = request.body.asFormUrlEncoded.map( _.filterKeys( _.startsWith(prefix)).map( m => m._1.patch(0, replace, prefix.length) -> m._2.head )).getOrElse(Map.empty)
def unprocessedFormParams(prefixes:Set[String])(implicit request:Request[AnyContent]):Map[String, String] = request.body.asFormUrlEncoded.map( _.filterKeys( !prefixes.contains(_) ).map( m => m._1 -> m._2.head )).getOrElse(Map.empty)
因此,这些功能也许应该是内涵还是分手了,但这里有云:preprocessedFormParms需要一个前缀和替换它:
val clientParams = preprocessFormParams("client_", "client.")
("client_id" -> "val1", "client_type" -> "val2") becomes ("client.id" -> "val1", "client.type" -> "val2")
时,我有参数中group.key1的形式,我group.key2可以嵌套在像这样的形式的情况下类
Form(mapping("client" -> mapping("type" -> nonEmptyText
"id" -> optional(nonEmptyText),
"secret" -> optional(nonEmptyText))
(RegisterClient.apply)(RegisterClient.unapply)
... more params ...)
(RegisterRequest.apply)(RegisterRequest.unapply)
在我的行动我先走,并筛选出我的每个组
implicit request =>
val clientParams = preprocessFormParams("client_", "client.")
val applicationParams = preprocessFormParams("application_", "application.")
val unprocessedParams = unprocessedFormParams(Set("client_", "application_"))
val processedForm = clientParams ++ applicationParams ++ unprocessedParams
最后我能将我的形式,像正常的,但现在我得到的嵌套结构我减少参数的个数,希望使类的情况下更易于管理。
clientRegistrationForm.bind(processedForm).fold( ... )
使用这种方法,你可以保持参数的数量下降。 如果你的参数没有可以方便地将像我的问题相同的前缀,那么你仍然可以使用相同的基本方法,但在其他指标分析筛选。
我不得不解决此限制的一天并没有发现这个SO发布,并与做事情的一种不同的方法,似乎它虽然看着有点靠不住的工作上来。
我们的表单组件
import play.api.data.Form
import play.api.data.Forms._
case class P1_18(f1: String,f2: String,f3: String,f4: String,f5: String,f6: String,f7: String,f8: String,f9: String,f10: String,f11: String,f12: String,f13: String,f14: String,f15: String,f16: String,f17: String,f18: String)
case class P2_18(f1: String,f2: String,f3: String,f4: String,f5: String,f6: String,f7: String,f8: String,f9: String,f10: String,f11: String,f12: String,f13: String,f14: String,f15: String,f16: String,f17: String,f18: String)
case class P36(f1: String,f2: String,f3: String,f4: String,f5: String,f6: String,f7: String,f8: String,f9: String,f10: String,f11: String,f12: String,f13: String,f14: String,f15: String,f16: String,f17: String,f18: String,f19: String,f20: String,f21: String,f22: String,f23: String,f24: String,f25: String,f26: String,f27: String,f28: String,f29: String,f30: String,f31: String,f32: String,f33: String,f34: String,f35: String,f36: String)
P36是你真正想要的对象,P1 / P2只是使用该框架的约束范围内建立起来的类,我在实际应用中取得这些私有的包装形式的对象。
然后,我们有我们的表单定义,这就是魔法发生:
val f = Form(
mapping(
"" -> mapping(
"f1" -> text,
"f2" -> text,
"f3" -> text,
"f4" -> text,
"f5" -> text,
"f6" -> text,
"f7" -> text,
"f8" -> text,
"f9" -> text,
"f10" -> text,
"f11" -> text,
"f12" -> text,
"f13" -> text,
"f14" -> text,
"f15" -> text,
"f16" -> text,
"f17" -> text,
"f18" -> text
)(P1_18.apply)(P1_18.unapply),
"" -> mapping(
"f19" -> text,
"f20" -> text,
"f21" -> text,
"f22" -> text,
"f23" -> text,
"f24" -> text,
"f25" -> text,
"f26" -> text,
"f27" -> text,
"f28" -> text,
"f29" -> text,
"f30" -> text,
"f31" -> text,
"f32" -> text,
"f33" -> text,
"f34" -> text,
"f35" -> text,
"f36" -> text
)(P2_18.apply)(P2_18.unapply)
)(
(p1, p2) =>
P36(
f1 = p1.f1,
f2 = p1.f2,
f3 = p1.f3,
f4 = p1.f4,
f5 = p1.f5,
f6 = p1.f6,
f7 = p1.f7,
f8 = p1.f8,
f9 = p1.f9,
f10 = p1.f10,
f11 = p1.f11,
f12 = p1.f12,
f13 = p1.f13,
f14 = p1.f14,
f15 = p1.f15,
f16 = p1.f16,
f17 = p1.f17,
f18 = p1.f18,
f19 = p2.f1,
f20 = p2.f2,
f21 = p2.f3,
f22 = p2.f4,
f23 = p2.f5,
f24 = p2.f6,
f25 = p2.f7,
f26 = p2.f8,
f27 = p2.f9,
f28 = p2.f10,
f29 = p2.f11,
f30 = p2.f12,
f31 = p2.f13,
f32 = p2.f14,
f33 = p2.f15,
f34 = p2.f16,
f35 = p2.f17,
f36 = p2.f18
)
)(
p => {
val p1 = P1_18(p.f1,p.f2,p.f3,p.f4,p.f5,p.f6,p.f7,p.f8,p.f9,p.f10,p.f11,p.f12,p.f13,p.f14,p.f15,p.f16,p.f17,p.f18)
val p2 = P2_18(p.f19,p.f20,p.f21,p.f22,p.f23,p.f24,p.f25,p.f26,p.f27,p.f28,p.f29,p.f30,p.f31,p.f32,p.f33,p.f34,p.f35,p.f36)
Option(
(p1,p2)
)
}
)
)
你可能会说:呵呵。 呃,对不起,你有一个绑定两次空键。 怎么可能可能工作呢? 我说:
val dataSeq = for(i <- 1 to 36) yield s"f${i}" -> s"text no. #${i}"
val filledFormFromMap = f.bind(dataSeq.toMap)
filledFormFromMap.value
// res9: Option[P36] = Some(P36(text no. #1,text no. #2,text no. #3,text no. #4,text no. #5,text no. #6,text no. #7,text no. #8,text no. #9,text no. #10,text no. #11,text no. #12,text no. #13,text no. #14,text no. #15,text no. #16,text no. #17,text no. #18,text no. #19,text no. #20,text no. #21,text no. #22,text no. #23,text no. #24,text no. #25,text no. #26,text no. #27,text no. #28,text no. #29,text no. #30,text no. #31,text no. #32,text no. #33,text no. #34,text no. #35,text no. #36))
也就是说,它实际是工作无故障。 与18-对象映射极限的问题不是形式不能支持多于18个字段内部但该结合可以不支持它。 然而,当我正看着ObjectMapping源我注意到,默认情况下, key
的ObjectMapping的是一个空字符串。 然后还与所述前缀,该场结合必将给定的前缀和:
val field1 = f1._2.withPrefix(f1._1).withPrefix(key)
这让我认识到形式的“顶部”只是一个空的关键。 对于除了猖獗的好奇没有理由我尝试过了两个空的钥匙,因为你可以看到在ObjectMapping 2是空的关键是在这两个领域中:
val field1 = f1._2.withPrefix(f1._1).withPrefix(key)
val field2 = f2._2.withPrefix(f2._1).withPrefix(key)
由于mappings
领域Mapping
仅仅是一个Seq[Mapping]
我想,下面的这一切,我们没有使用地图,其中键会冲突的深层合并方法和诸如此类的东西,但这样的组合在非-destructive时尚,因为他们都有这个顶级关键是如何玩(我相信)生成您的field.nested.thing
根据您如何嵌套的映射自身的映射。 所以,这一切的一切,这意味着你可以有多个绑定到相同的密钥(或至少是为空字符串),因此可以通过分解成更小的组件,然后提供手动构建任何超过18场大型apply
与unapply
方法结合起来的东西(如反对尝试使用P36.apply和P36.unapply因为这些不会因为元组限制,我相信工作)