2012-10-18 14 views
8

mam ten odtwarzania kodu ramy 2 (uproszczony):Zdefiniuj klasę abstrakcyjną lub cechę, która zależy od niejawny

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 klasa rozszerza Entity, i to obiekt towarzysz IdeaType rozciąga EntityCompanion.

Jak można się spodziewać, nie mam tego rodzaju kodu w każdym kontrolerze, więc chciałbym, aby wyodrębnić podstawowe zachowanie do cechę, coś takiego:

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))) 
    } 
} 

Ale pojawia się następujący błąd :

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

nie wiem jak powiedzieć, że niejawna Writes będą realizowane przez klasy wykonawczych cechę EntityController (lub odziedziczenie klasy abstrakcyjnej EntityController)

- edycja

tak daleko teraz robię to tak:

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

i używać go jak ten

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

could't dostać scala automatycznie odebrać go za pomocą implicits. Próbowałem z tym importem, ale to nie działa

import formatters.json.IdeaTypeFormatter._ 
+0

+1, pomyślałem tak samo, jak oddzielić zwykłe operacje CRUD w Grze. Twoja sprawa, odpowiedź JSON, jest łatwiejsza niż radzenie sobie z mieszanym JSON i views.html content + authentication. Lot's 'boilerplate ... – virtualeyes

Odpowiedz

7

Jeśli chcesz klas same Controler zdefiniować niejawny, a potem po prostu zadeklarować abstrakcyjnych wartości ukrytych i zdefiniować je w klasach pochodnych.

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

Jednak jest to o wiele bardziej praktyczne, aby określić te implicits poza kontrolerem, zazwyczaj w obiekcie towarzyszem swojej jednostki, tak, że kompilator może znaleźć je automatycznie bez importu. Następnie przekazać wartości domniemane dla konstruktora 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] { 
    ... 
} 

ostatnia uwaga, domniemane do listy [MyEntity] prawdopodobnie niepotrzebne (a więc tylko ukryte dla MyEntity musiałyby być wyraźnie określona). Nie sprawdziłem, ale zwykle przy używaniu tego "wzoru typograficznego", framework zdefiniuje już niejawne dla każdej listy [T], pod warunkiem, że istnieje domniemane dla T. Jest to prawdopodobnie przypadek, chociaż nie sprawdziłem .

Powiązane problemy