大型多模块播放框架应用程序

时间:2014-04-14 20:03:28

标签: scala playframework playframework-2.0

是否有大型多模块播放框架(Scala)应用程序的示例。例如,使用多个视觉主题并根据主题提供不同的内容。为这些应用程序组织代码的最佳方法是什么。

1 个答案:

答案 0 :(得分:2)

我认为你的问题有两点不同:

  • 如何将大型播放应用程序拆分为更小,更易于管理的模块?
  • 如何为同一个动态选择不同的视图(即有多个主题来渲染相同的数据)?

第一点非常简单,尽管在线文档中没有明确说明(AFAIK)。一出戏!模块就像常规播放应用程序一样构建,但没有任何配置文件。基本上,删除任何应用程序的conf/文件夹,将其发布到您喜欢的存储库中,然后您就可以将该模块用作另一个应用程序/模块中的依赖项。

第二点有点棘手。由于播放模板是静态编译的,因此在运行时更改视图是不受支持的,您必须提供自己的解决方案。

第一个解决方案是使用不同的模板引擎,一个在运行时this blog post解释模板的模板引擎,解释如何在play 2.X应用程序中使用scalate模板引擎。

另一种解决方案是使用运行时反射来在运行时选择正确的模板,但代价是失去一些编译时保护措施(如果不存在所需的模板,则会出现运行时错误,而不是像常规应用程序中那样的编译时错误。)

第三种解决方案是在父模块中从控制器中抽象模板和路由(使它们成为特征或抽象类),然后为每个不同的主题创建一个子应用程序,每个子应用程序只需要实现抽象控制器通过提供所需的模板和路线:

// in the parent module
trait AbsCtrl extends Controller {
  val indexTemplate : (Foo, Bar) => Html // a template is like a function
                                         // from some models to Html
  val errorRoute : Call

  def index() = Action {
    request =>
      val foo = Foo()
      val bar = Bar()
      if(someCondition) Ok(indexTemplate(foo, bar))
      else Redirect(errorRoute)
  }
}

// in the child module 
object Ctrl extends AbsCtrl {
  // assuming you have a scala template named index that take the right arguments
  override val indexTemplate = views.html.index.render
  override val errorRoute = routes.Application.error()
}   

这个解决方案涉及更多,它需要每个主题有一个应用程序,这在某些情况下可能是不可接受的,但它保留了编译时的安全性,因此与前一个相比可能更好。

最后,您可以选择将系统拆分为两个不同的层:

  • 播放应用程序中的业务层,使用简单的REST API
  • 面向最终用户的渲染层,它将使用业务API并处理特定于主题的渲染

您可以使用其他技术编写后者,例如,一个简单的node.js服务器,可以让您利用基于javascript的模板引擎。