作为一个使用Lift约两年的人,以下是我的个人看法:
1) 路由:在路由更改时,整个路由控制器结构都需要重新编译:不好
Lift中没有路由。我认为最接近的相关概念应该是SiteMap,就个人而言,我从来没有遇到过与其编译有关的问题。
2) REST似乎不被直接支持,因为路由POST /foo/bar/:id会与DELETE /foo/bar/:id冲突;即路由路径必须唯一,可能是为了反向路由。
通过使用Lift,我已经做了很多REST,并且可以告诉你这绝对不是问题。Lift的REST支持非常棒, 并且基于Scala的模式匹配,这为您设计Web服务提供了一个非常强大、类型安全的方式。
"3) views: 每个foo操作都有一个scala.html文件,文件数量增加很快,这意味着编译时间变慢,需要编译的内容也更多;由于缺乏IDE支持(当然,据我所知,目前没有任何Scala模板引擎提供IDE支持),泛型不受支持,盲目编码尤其困难。"
"Lift中,HTML代码仅仅是HTML(没有特殊符号),因此根本不会影响编译时间。HTML(称为模板)通过Snippet进行处理,将NodeSeq => NodeSeq转换。这听起来很复杂,但是Lift有一个DSL让它变得非常容易。想要将用户姓名添加到span标签中吗?如果它看起来像下面这样: "
<span id="user-name">User name goes here</span>
在您的代码片段中可能会有这样的代码:
"#user-name *" #> user.name
你可以在模板中重复使用项目,比如表格或列表:
<table id="table"><tr><td class="name"></td><td class="value"></td></tr></table>
应用此后:
val tuples = List(("Lift", "Is great"), ("Other web frameworks", "Eh"))
"#table" #> {
"tr" #> {
tuples map { case(name, value) =>
".name" #> name &
".value" #> value
}
}
}
会生成一个表格,其中有两行,每一行代表列表中元素的名称/值。
我认为这真的是Lift最大的优势之一。模板只是HTML,没有符号或标记。你可以直接使用设计师提供的内容,并且甚至可以让他们直接进行更新(在某些情况下)。
另一方面,片段是纯Scala,而不是某种模板语言。您可以在Snippet中使用Scala的所有功能,并且它都经过编译器检查。
还可以(并且鼓励)在多个页面上使用Snippet,因此您不一定需要每个页面都有一个Snippet。您甚至可以配置Sitemap以在多个页面上使用相同的模板,并根据请求向页面包含的Snippets传递类型安全参数。
“4)增量构建可以工作,但是该过程中没有任何东西可以称之为“快速”,即使对scala.html文件进行简单更改实际上也需要@2秒的时间,这在您想要即时代码更改浏览器刷新反馈循环时是很长的时间。”
我认为Lift在这方面并没有什么问题,但不幸的是它也没有太多帮助。很高兴听到Scala 2.10将在这个领域包含一些改进,因为我认为它们必须来自编译器。
回答一些Lift的批评...
需要高级Scala吗? 不,我不认为需要。 这有点主观,但您可以从我发布的内容中看到,创建模板并将片段应用于它相当简单。 您必须熟悉像“map”这样的概念,但如果您不熟悉,使用Scala Web框架有什么好处呢? 对于新手来说,他们可能更好地遵循Wiki Cookbook和Simply Lift中的示例,而不是API文档,但我认为这是Scala习惯用语,而不是Lift用语。
你是否必须在“控制器”中混合标记?绝对不是。我将忽略Lift不是MVC框架的事实,并假设发布者谈论的是Snippets。从Snippet输出HTML绝不是必要的,在大多数情况下是完全反模式。像我发布的那样的CSS选择器允许您将所有HTML保存在模板文件中,将所有逻辑保存在Snippet中。
Lift需要太多状态吗?这是我遇到的头号投诉,但我从未见过它伴随着真正的世界问题。事实是,使用Lift时,您可以选择是否要有状态。如果您正在使用Lift编写Web服务,并且在访问URL时不希望创建会话,则可以使用LiftRules.statelessDispatchTable为该服务注册。这符合Lift哲学,即状态既不好也不坏,但它对于满足某些需求是必要的,而对于其他需求则不是必要的。重要的是明确何时使用它并让开发人员决定。如果您想了解更多详细信息,请参考David Pollack的
better explanation。