Scala 真的对片段感到困惑吗

Scala 真的对片段感到困惑吗,scala,lift,Scala,Lift,我的电梯视图有问题。问题是,我正在进行两次代价高昂的远程RESTAPI调用——实际上我只需要做一次 但我不知道怎么解决这个问题 基本上我有这样一个HTML模板,它需要显示用户列表及其计数: //UserSearchResults.html Num users: <span class="lift:UserSearchResults.userCount"></span> User list: <ul> <lift:UserSearchResults.u

我的电梯视图有问题。问题是,我正在进行两次代价高昂的远程RESTAPI调用——实际上我只需要做一次

但我不知道怎么解决这个问题

基本上我有这样一个HTML模板,它需要显示用户列表及其计数:

//UserSearchResults.html

Num users: <span class="lift:UserSearchResults.userCount"></span>

User list:
<ul>
<lift:UserSearchResults.userList>   
   <li><user:userName/></li>
</lift:UserSearchResults.userList>    
</ul>
//UserSearchResults.html
Num用户数:
用户列表:
然后我有一个实际的代码片段,它从RESTAPI服务器检索用户列表。但是,请注意,它实际上会执行两次—一次用于计算用户数,一次用于呈现列表

  //UserSearchResults.scala 

  /** Get list of users from api */
  def users: List[User] = {
    val url = "http://server/rest-api/user-search";
    val result = io.Source.fromURL(url).mkString

    //... parse users into List[User] and return it

    return entries
  }

  /** Render user count */
  def userCount =
    "* *" #> users.length    //<-- ONE call

  def userList(in: NodeSeq): NodeSeq = {
    users.flatMap(user => Helpers.bind("user", in,  //<--SECOND call
      "userName" -> user.user_name)) 
  }
//UserSearchResults.scala
/**从api获取用户列表*/
def用户:列表[用户]={
val url=”http://server/rest-api/user-search";
val result=io.Source.fromURL(url).mkString
//…将用户解析到列表[User]中并返回它
返回条目
}
/**渲染用户计数*/
def用户计数=
“**”#>users.length//Helpers.bind(“user”,in,//user.user\u name))
}
有更好的地方放置api调用吗?是否有类似于代码段的“构造函数”,我可以使用它缓存用户列表,并在类中的所有函数中共享它


非常感谢您的帮助。

如果您的代码段扩展了StatefulSnippet,您只需将列表保存在实例变量中即可。另一种选择是将列表放入RequestVar中。然后还可以从其他代码段访问它。

如果UserSearchResults是一个类(而不是一个对象),那么该类将有一个每个请求的实例。因此,您所要做的就是将您的def用户更改为懒惰的val用户,您应该可以开始了。

哇,这正是我想要的!有没有办法不使用“lazy”(我还没有读到scala的特性)?@drozzy
lazy val
定义了一个值,该值只有在使用它的值时才会计算,并且保证只计算一次。这非常适合这种情况。附言:任何时候你想回答scala/lift的问题,请查阅我的个人资料——我总是有一大堆愚蠢的问题,似乎没有人愿意回答!呵呵。行。正如比尔指出的,在这种情况下,lazy val可能很有用。这是一种记录结果的方式。如果您熟悉Ruby或JS,这与说“variable=variable | |<计算变量值的函数>”一样,只不过是线程安全的,而且更好。也就是说,如果每次使用该代码段时都需要相关的值,只需将其设置为常规val即可。顺便说一下,您可以使用整个块来确定变量或延迟val的初始值,因此不需要更改语法。