我有一个应用程序控制器,它有两种方法。在第一种方法中,我访问数据库并检索表单的下拉元素列表。我将检索到的元素存储在类级变量中。在第二种方法中,如果出现错误,则显示表单,否则显示结果。问题是我的类级变量返回空。
class Application extends Controller {
var appList = Seq[AppDetail]()
var countryList = Seq[Country]()
def home(page:Int,filter: String): Action[AnyContent] = Action.async { implicit request =>
val futures = for {
appDetails <- AppDetailsDAO.listAll() //DB retrieve
countries <- CountriesDAO.listAll() //DB retrieve
} yield (appDetails, countries)
futures.map{case (appDetails, countries) => {
appList = appDetails
countryList = countries
Ok(appList, countryList)
}
}
def result(page:Int, filter: String): Action[AnyContent] = Action.async { implicit request =>
analyticForm.bindFromRequest.fold(
formWithErrors => {
Future.successful(BadRequest(html.home(formWithErrors, appList, countryList)) //appList, countryList returns empty
},
analyticData => {
Ok(appList, countryList) //appList, countryList returns empty
}
}
}
答案 0 :(得分:1)
Play是一个RESTful框架。这意味着,除其他外,您不应在两个请求之间共享信息。请求总是无状态。
要解决您的问题,您只需在两个操作中获取appList
和countryList
即可。同时删除控制器中的两个var
。尽可能避免scala中的可变变量(尽管在某些情况下它们可能很有用)。请参阅Daniel C. Sobral关于the difference between var and val的答案。
未经测试的代码:
class Application extends Controller {
def home(page:Int,filter: String): Action[AnyContent] = Action.async { implicit request =>
fetchDb.map{case (appDetails, countries) => {
appList = appDetails
countryList = countries
Ok(appList, countryList)
}}
}
def result(page:Int, filter: String): Action[AnyContent] = Action.async { implicit request =>
fetchDb.map{case (appDetails, countries) => {
analyticForm.bindFromRequest.fold(
formWithErrors => {
BadRequest(html.home(formWithErrors, appList, countryList))
},
analyticData => {
Ok(appList, countryList) //appList, countryList returns empty
}
)
}}
}
def fetchDb = {
val fAppDetails = AppDetailsDAO.listAll()
val fCountries = CountriesDAO.listAll()
for {
appDetails <- fAppDetails
countries <- fCountries
} yield (appDetails, countries)
}
}
附注:您可能已经注意到我在Future
之外创建了fetchDb
个实例以进行理解。这是因为for comprehension只是嵌套平面地图的另一种表示。这意味着countries
在appDetails
完成之前不会运行。期货将按顺序运行。如果你把它们放在理解之外,它们就会并行运行。