제 생각에는 템플릿이 정적으로 입력된다는 사실은 실제로 좋은 것입니다. 컴파일하면 템플릿을 호출해도 실패하지 않을 것입니다.
그러나 실제로 호출 사이트에 약간의 상용구를 추가합니다. 그러나 정적 타이핑 이점을 잃지 않고 줄일 수 있습니다 .
스칼라에서는 두 가지 방법으로 작업 구성을 통해 또는 암시 적 매개 변수를 사용합니다. Java에서는 Http.Context.args
맵을 사용하여 유용한 값을 저장하고 템플릿 매개 변수로 명시 적으로 전달하지 않고도 템플릿에서 값을 검색하는 것이 좋습니다 .
암시 적 매개 변수 사용
장소 menus
당신의 말에 매개 변수를 main.scala.html
템플릿 매개 변수와 "암시"로 표시 :
@(title: String)(content: Html)(implicit menus: Seq[Menu])
<html>
<head><title>@title</title></head>
<body>
<div>
@for(menu<-menus) {
<a href="#">@menu.name</a>
}
</div>
@content
</body>
</html>
이제이 기본 템플릿을 호출 menus
하는 main
템플릿이있는 경우 이러한 템플릿에서 암시 적 매개 변수로 선언 된 경우 Scala 컴파일러 에서 템플릿으로 암시 적으로 매개 변수를 전달할 수 있습니다.
@()(implicit menus: Seq[Menu])
@main("SubPage") {
...
}
그러나 컨트롤러에서 암시 적으로 전달하려면 템플릿을 호출하는 범위에서 사용 가능한 암시 적 값으로 제공해야합니다. 예를 들어 컨트롤러에서 다음 메소드를 선언 할 수 있습니다.
implicit val menu: Seq[Menu] = Menu.findAll
그런 다음 작업에서 다음을 작성할 수 있습니다.
def index = Action {
Ok(views.html.index())
}
def index2 = Action {
Ok(views.html.index2())
}
이 방법에 대한 자세한 내용은 이 블로그 게시물 및 이 코드 샘플 에서 확인할 수 있습니다 .
업데이트 :이 패턴을 보여주는 멋진 블로그 게시물도 여기 에 작성 되었습니다 .
활동 구성 사용
실제로, RequestHeader
값을 템플릿 에 전달하는 것이 종종 유용합니다 (예 : 이 샘플 참조 ). 암시 적 요청 값을 수신하는 조치를 쉽게 작성할 수 있으므로 컨트롤러 코드에 상용구를 추가하지 않습니다.
def index = Action { implicit request =>
Ok(views.html.index()) // The `request` value is implicitly passed by the compiler
}
따라서 템플릿에는 종종이 암시 적 매개 변수가 수신되기 때문에 메뉴를 포함하는 더 풍부한 값으로 대체 할 수 있습니다. Play 2 의 액션 구성 메커니즘을 사용하면 됩니다.
이렇게하려면 Context
기본 요청을 래핑 하여 클래스 를 정의해야합니다 .
case class Context(menus: Seq[Menu], request: Request[AnyContent])
extends WrappedRequest(request)
그런 다음 다음 ActionWithMenu
방법을 정의 할 수 있습니다 .
def ActionWithMenu(f: Context => Result) = {
Action { request =>
f(Context(Menu.findAll, request))
}
}
다음과 같이 사용할 수 있습니다 :
def index = ActionWithMenu { implicit context =>
Ok(views.html.index())
}
템플릿에서 컨텍스트를 암시 적 매개 변수로 사용할 수 있습니다. 예 main.scala.html
:
@(title: String)(content: Html)(implicit context: Context)
<html><head><title>@title</title></head>
<body>
<div>
@for(menu <- context.menus) {
<a href="#">@menu.name</a>
}
</div>
@content
</body>
</html>
작업 구성을 사용하면 템플릿에 필요한 모든 암시 적 값을 단일 값으로 집계 할 수 있지만 반면에 유연성은 떨어질 수 있습니다.
Http.Context 사용 (자바)
Java에는 스칼라의 암시 적 메커니즘 또는 이와 유사한 기능이 없으므로 템플릿 매개 변수를 명시 적으로 전달하지 않으려면 Http.Context
요청 기간 동안 만 존재 하는 오브젝트에 템플릿을 저장하는 것이 가능합니다 . 이 객체 args
는 유형 의 값을 포함합니다 Map<String, Object>
.
따라서 문서에 설명 된대로 인터셉터를 작성하여 시작할 수 있습니다 .
public class Menus extends Action.Simple {
public Result call(Http.Context ctx) throws Throwable {
ctx.args.put("menus", Menu.find.all());
return delegate.call(ctx);
}
public static List<Menu> current() {
return (List<Menu>)Http.Context.current().args.get("menus");
}
}
정적 메소드는 현재 컨텍스트에서 메뉴를 검색하는 간단한 방법입니다. 그런 다음 컨트롤러에 Menus
조치 인터셉터 와 혼합되도록 주석을 답니다 .
@With(Menus.class)
public class Application extends Controller {
// …
}
마지막 menus
으로 다음과 같이 템플릿 에서 값을 검색하십시오 .
@(title: String)(content: Html)
<html>
<head><title>@title</title></head>
<body>
<div>
@for(menu <- Menus.current()) {
<a href="#">@menu.name</a>
}
</div>
@content
</body>
</html>