ope*_*sas 8 inheritance scala traits playframework-2.0
我有这个play框架2代码(简化):
import formatters.json.IdeaTypeFormatter._
object IdeaTypes extends Controller {
def list = Action { request =>
Ok(toJson(IdeaType.find(request.queryString)))
}
def show(id: Long) = Action {
IdeaType.findById(id).map { ideatype =>
Ok(toJson(ideatype))
}.getOrElse(JsonNotFound("Type of idea with id %s not found".format(id)))
}
}
Run Code Online (Sandbox Code Playgroud)
IdeaTypeclass extends Entity,它的伴随对象IdeaType,扩展EntityCompanion.
正如您所料,我在每个控制器中都有这种代码,因此我想将基本行为提取到特征中,如下所示:
abstract class EntityController[A<:Entity] extends Controller {
val companion: EntityCompanion
val name = "entity"
def list = Action { request =>
Ok(toJson(companion.find(request.queryString)))
}
def show(id: Long) = Action {
companion.findById(id).map { entity =>
Ok(toJson(entity))
}.getOrElse(JsonNotFound("%s with id %s not found".format(name, id)))
}
}
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
[error] EntityController.scala:25: No Json deserializer found for type List[A].
[error] Try to implement an implicit Writes or Format for this type.
[error] Ok(toJson(companion.find(request.queryString)))
[error] ^
[error] EntityController.scala:34: No Json deserializer found for type A.
[error] Try to implement an implicit Writes or Format for this type.
[error] Ok(toJson(entity))
[error] ^
Run Code Online (Sandbox Code Playgroud)
我不知道如何判断隐式Writes将由实现EntityController特征的类实现(或继承抽象类EntityController)
- 编辑
到目前为止我现在这样做:
abstract class CrudController[A <: Entity](
val model: EntityCompanion[A],
val name: String,
implicit val formatter: Format[A]
) extends Controller {
Run Code Online (Sandbox Code Playgroud)
并像这样使用它
object CrudIdeaTypes extends CrudController[IdeaType](
model = IdeaType,
name = "type of idea",
formatter = JsonIdeaTypeFormatter
)
Run Code Online (Sandbox Code Playgroud)
我不能让scala使用implicits自动选择它.我试过这个导入但它没有用
import formatters.json.IdeaTypeFormatter._
Run Code Online (Sandbox Code Playgroud)
如果您希望控制器类本身定义隐式,那么只需声明抽象隐式值,并在派生类中定义它们.
abstract class EntityController[A<:Entity] extends Controller {
protected implicit def entityWriter: Writes[A]
protected implicit def entityListWriter: Writes[List[A]]
...
}
class MyEntity extends Entity {
...
}
class MyEntityController extends EntityController[MyEntity] {
protected def entityWriter: Writes[MyEntity] = ...
protected def entityListWriter: Writes[List[MyEntity]] = ...
}
Run Code Online (Sandbox Code Playgroud)
但是,在控制器外部定义这些隐含更为实际,通常在实体的伴随对象中,以便编译器可以自动找到它们而无需导入.然后,将隐式值传递给以下构造函数EntityController:
abstract class EntityController[A<:Entity](implicit entityWriter: Writes[A], entityListWriter: Writes[List[A]] ) extends Controller {
...
}
class MyEntity extends Entity {
...
}
object MyEntity {
protected implicit def entityWriter: Writes[A]
protected implicit def entityListWriter: Writes[List[A]]
}
class MyEntityController extends EntityController[MyEntity] {
...
}
Run Code Online (Sandbox Code Playgroud)
最后一点,List [MyEntity]的隐式可能是不需要的(因此只需要明确定义MyEntity的隐式).我没有检查过,但通常在使用这个"类型类模式"时,框架已经为每个List [T]定义了一个隐式,只要有一个隐含的T.虽然我没有检查过,但情况可能就是这样.