私のメインビューテンプレートでは、データベースからの動的なデータ、たとえばウェブサイトのナビゲーション項目を表示したいと考えています。すべてのコントローラでコードを重複させずにモデルをメインビューテンプレートに渡すにはどうすればよいですか?
モデルをテンプレートにパラメータとして追加すると、メインテンプレートを使用するすべてのビューでメインテンプレートのモデルを指定する必要があります。したがって、すべてのコントローラのすべてのアクションは、最初にメインテンプレートのナビゲーションモデルをフェッチする必要があります。
このアプローチは、すべてのアクションがメインテンプレートモデルを取得する方法を知る必要があるため、コードの重複と単一責任の原則の違反につながります。コードをテスト可能な状態に保ちながら、コードの重複なしに記述された機能を孤立した方法で提供する方法はありますか?
例
次モデル及びサービスクラスを模擬するために使用することができる。
package services
import scala.concurrent.Future
case class HeaderItem(title: String, url: String)
case class User(name: String, email: String)
class HeaderItemService {
val all: Future[Seq[HeaderItem]] = Future.successful(HeaderItem("Home", "/") :: Nil)
}
class UserService {
val all: Future[Seq[User]] = Future.successful(User("Test", "[email protected]") :: Nil)
}
メインビュー・テンプレートは、ヘッダ項目を表示:
@import services.HeaderItem
@(headerItems: Seq[HeaderItem])(content: Html)
<!DOCTYPE html>
<html lang="en">
<body>
<div id="header">
<ul>
@for(item <- headerItems) {
<li>@item.title</li>
}
</ul>
</div>
@content
</body>
</html>
子ビューディスプレイ特定のデータ(ユーザー)を表示し、メインテンプレート固有のデータをテンプレートに渡す必要があります。
@import services.HeaderItem
@import services.User
@(headerItems: Seq[HeaderItem], users: Seq[User])
@main(headerItems) {
<ul>
@for(user <- users) {
<li>@user.name</li>
}
</ul>
}
そして、これはうまくナビゲーション項目だけでなく、ユーザーとして気にする必要がありますコントローラです。
package controllers
import javax.inject._
import play.api.mvc._
import services.{HeaderItemService, UserService}
import scala.concurrent.ExecutionContext.Implicits.global
@Singleton
class HomeController @Inject()(headerItemService: HeaderItemService, userService: UserService) extends Controller {
def index = Action.async {
for {
headerItems <- headerItemService.all
users <- userService.all
} yield Ok(views.html.index(headerItems, users))
}
}
まずしようとする問題は、レンダリングにより近づくことができASP MVCで
Html.RenderActionメソッド(https://msdn.microsoft.com/en-us/library/ee839451(v=vs.100).aspx)を使用して、ビュー内のアクション。私が知る限り、同様のアプローチは、プレイフレームワーク(2.4)では不可能です。
別のエンドポイントからヘッダ項目をフェッチするメインテンプレートでjavascriptを使用することができます –
@Lukasz:javascriptを使用して、私は実際にASP RenderActionアプローチと同様のソリューションを構築できましたが、新しい依存関係をもたらし、読みにくい私はScalaだけに基づいたソリューションを好むだろう。 – Felix