2012-10-18 80 views
8

我有這樣的發揮框架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))) 
    } 
} 

IdeaType類擴展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))) 
    } 
} 

但我得到以下錯誤:

[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]    ^

我不知道如何告訴隱含Writes將通過實現EntityController特徵(或繼承抽象類EntityController

的類來實現

- 編輯

到目前爲止,我現在做這樣的:

abstract class CrudController[A <: Entity](
    val model: EntityCompanion[A], 
    val name: String, 
    implicit val formatter: Format[A] 
) extends Controller { 

,並使用它像這樣

object CrudIdeaTypes extends CrudController[IdeaType](
    model = IdeaType, 
    name = "type of idea", 
    formatter = JsonIdeaTypeFormatter 
) 

我便無法得到斯卡拉自動選擇使用它implicits。我試着用這個進口,但如果你想在CONTROLER類本身來定義隱式的,那麼就宣告抽象的隱含價值,並在派生類中定義它們沒有工作

import formatters.json.IdeaTypeFormatter._ 
+0

+1,想都一樣,如何抽象掉Play中常見的CRUD操作。你的情況,JSON響應,比處理混合的JSON和views.html內容+認證更容易。羅特的模板... – virtualeyes

回答

7

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]] = ...  
} 

但是,它是更實際來定義這些implicits控制器之外,通常在實體的同伴對象,讓他們的編譯器可以在不導入自動找到它們。 然後,通過隱含值的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] { 
    ... 
} 

最後一點,隱含列出[myEntity所]可能是不需要的(因此只有隱含的myEntity所需要被明確定義)。我沒有檢查過,但通常在使用這個「類型模式」時,框架將已經爲每個List [T]定義了一個隱式,只要T有一個隱式。這可能是這種情況,儘管我沒有檢查過。