Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Forms 我可以在scala中使用协方差传递不同的表单数据类型吗?_Forms_Scala_Types_Playframework_Covariance - Fatal编程技术网

Forms 我可以在scala中使用协方差传递不同的表单数据类型吗?

Forms 我可以在scala中使用协方差传递不同的表单数据类型吗?,forms,scala,types,playframework,covariance,Forms,Scala,Types,Playframework,Covariance,以同样的方式,缔约国声明: 对于某些类列表[+A],产生协变意味着对于两种类型 A和B其中A是B的子类型,则列表[A]是B的子类型 名单[B] 这是否也适用于表单(如scala表单)?我在通过各种形式的表格时遇到了问题。下面是我正在做的一个示例: abstract class SuperCovariance case class TestCovariance1(id: Option[Int], name: String, another: String) extends Super

以同样的方式,缔约国声明:

对于某些类列表[+A],产生协变意味着对于两种类型 A和B其中A是B的子类型,则列表[A]是B的子类型 名单[B]

这是否也适用于
表单
(如scala表单)?我在通过各种形式的表格时遇到了问题。下面是我正在做的一个示例:

   abstract class SuperCovariance

   case class TestCovariance1(id: Option[Int], name: String, another: String) extends SuperCovariance

   case class TestCovariance2(id: Option[Int], differentName: String, other: String) extends SuperCovariance

   object Tc1Form {

     val form = Form(
       mapping(
         "_id" -> optional(number),
         "name" -> nonEmptyText,
         "another" -> nonEmptyText
       )(TestCovariance1.apply)(TestCovariance1.unapply)
     )

   }

   object Tc2Form {

     val form = Form(
       mapping(
         "_id" -> optional(number),
         "differentName" -> nonEmptyText,
         "other" -> nonEmptyText
       )(TestCovariance2.apply)(TestCovariance2.unapply)
     )

   }
如果其中一种形式可以作为方法中的参数传递,我想我可以这样做:

     def acceptAnySubTypeOfSuperCovariance(myForm: Form[SuperCovariance])(implicit request: Request[AnyContent]): Result = {
       Ok(views.html.myTemplate(myForm))
     }
调用此方法并传递
表单[TestConvariace1]
类型会导致一个错误,这导致我在理解和如何避免为
超方差的每个子类型编写此类方法时遇到问题。欢迎任何帮助/启发


为了阐明我希望能够做到这一点的理由,是为了避免为每个表单编写重复的代码行。因此,如果我有多个表单,我希望控制器中有一个方法绑定来自请求的数据,例如

   def updateDoc(collectionName: String, oId: Option[BSONObjectID]) = Action.async { implicit request: Request[AnyContent] =>

       MyModel.form.bindFromRequest.fold(
         errorForm => Future.successful(Ok(views.html.errorTemplate(errorForm, MyModel)),
         data => {

           val updatedDoc = ?? // map data to model here, e.g. TestCovariance1(None, data.name, data.another)

           // calls a method 
           updateMultipleFields[MyModel](collectionName, updatedDoc, oId).map(x =>
             Redirect(routes.DatabaseC.editIndex(collName, oId.get))
           )

         }
       )
   }

  // generic method to update fields in collection (Mongo database)
  def updateMultipleFields[T](collectionName: String, model: T, id: Option[BSONObjectID])(implicit writes: Writer[T]): Future[Result] = {

    val idSelector = Json.obj("_id" -> id)
    getCollection(collectionName).flatMap(collection =>
      collection.update(idSelector, Json.obj("$set" -> model)).map {
        lastError =>
          Created("fields updated")
      }
    )

  }

我认为MVC结构将是灵活的,它允许我以这样一种方式设置数据处理:如果正确地(安全地)进行设置;我可以通过创建新模型(表单和模型)简单地添加数据。如果我不能;这并不妨碍应用程序的功能,但似乎重复这些锅炉板状代码是Scala存在的原因之一。

不,我不认为您提到的链接引用的内容可以在示例中使用。为了实现这一点,
表单
类本身应该在
T
表单[+T]
中声明为协变,而他们不能这样做,因为它用于双向转换。不过你还是可以做一些你想做的事情

 def acceptAnySubTypeOfSuperCovariance[T:<SuperCovariance](myForm: Form[T])(implicit request: Request[AnyContent]): Result = 

def acceptionSubtypeOfSuperConvariance[T:抛出了什么错误?我认为在这种情况下不需要强制执行协方差。@nicodp错误为-*类型不匹配,预期为:Form[superConvariance],预期为:Form[TestConvariance],预期为:Form[TestConvariance],抱歉-typo:*类型不匹配,预期为:Form[superConvariance],实际为:Form[TestConvariance1]*感谢您的回答(抱歉延迟回复)。我已编辑了上面的原始问题,希望这能让我更清楚地了解我为什么要这样做。