注解: 这是对《Learning Play! Framework 2》第三章的学习
本章是一个显示聊天记录的项目,只有一个页面,可以自动对聊天记录进行排序、分组和显示,并整合使用了less,其界面显示如下
一、项目结构
二、项目中使用的模型
所有的聊天记录放在models目录中Chat类中
public class Chat { public DateTime date; // chat time public int occurrence; // chat room public List<Item> items; //chat content public Chat(DateTime date, int occurrence, List<Item> items) { this.date = date; this.occurrence = occurrence; this.items = items; } }
每一次的聊天记录的内容放在models目录中Item类中
public class Item { public String user; public LocalTime timestamp; public String message; public Item(String user, LocalTime timestampLocalTime, String message) { this.user = user; this.timestamp = timestampLocalTime; this.message = message; } }
三、项目route
本项目只有一个页面,所有不用修改默认的route
四、项目模板
4.1 index.scala.html模板
@(message: String)(chats:List[Chat]) @import models.Item @import java.util.List @main("Welcome to the Packt Publishing's Play 2.0 Demo") { <h1>@message</h1>
@chats.sortBy(_.occurrence).groupBy(_.date.toDate).toSeq.sortBy(_._1).map { dateAndChats => <h3>-- Chat @dateAndChats._1 --</h3> @dateAndChats._2.map { chat => @listContainer{ //引用listContainer模板 <h3>-- Chat #@chat.occurrence --</h3> }(chat) { <hr/> } } } }
说明: 引用listContainer模板方法说明
@listContainer{ <h3>-- Chat #@chat.occurrence --</h3> }(chat) { <hr/> }
-
- <h3>是在listContainer模板前面加入的内容
- (chat)是在listContainer模板的参数
- <hr/>是在listContainer模板前面后面的内容
- 聊天内容的分组、排序
@chats.sortBy(_.occurrence).groupBy(_.date.toDate).toSeq.sortBy(_._1).map{ dateAndChats =>
这里定义了一个变量dateAndChats,该变量已经分组(按聊天室编号occurrence)和排序(按日期date)好了。
4.2 listContainer.scala.html模板
@(header:Html)(chat:Chat)(footer:Html) @import models.Chat
<div style="margin-left:@{5*chat.occurrence}%"> @header <ul> @chat.items.map { item => @listItem(item) //引用listItem模板 } </ul> @footer </div>
4.3 listItem.scala.html模板
@(item:Item) @import models.Item <style> li.item span{ width:100px;display:inline-block;} </style> <li class="item"> <span>@item.user</span> <span>[@item.timestamp]</span>@item.message </li>
五、controller
本例比较简单,只有一个controller,在controllers目录中Application类
public class Application extends Controller { public static Result index() { DateTime today = DateTime.now(); DateTime yesterday = today.minus(Days.ONE); //模拟数据 Chat chat11 = new Chat(yesterday, 1, asList( new Item("me", LocalTime.now(), "Hello!"), new Item("other", LocalTime.now(), "Hi!"), new Item("me", LocalTime.now(), "Fine?"), new Item("other", LocalTime.now(), "Yes") )); Chat chat12 = new Chat(yesterday, 2, asList( new Item("me", LocalTime.now(), "It's hot today!"), new Item("other", LocalTime.now(), "Indeed...") )); Chat chat21 = new Chat(today, 1, asList( new Item("me", LocalTime.now(), "Hello!"), new Item("me", LocalTime.now(), "Youhou?"), new Item("no-one", LocalTime.now(), "...") )); Chat chat22 = new Chat(today, 2, asList( new Item("me", LocalTime.now(), "Ding ding!"), new Item("me", LocalTime.now(), "Poueeeeeeeeeet?"), new Item("no-one", LocalTime.now(), "...") )); Chat chat23 = new Chat(today, 3, asList( new Item("me", LocalTime.now(), "No one?"), new Item("no-one", LocalTime.now(), "Yes?") )); return ok(index.render("It Works!", asList(chat23, chat11, chat21, chat12, chat22))); } }
在该controller中,我们模拟了一些数据(没有使用数据库),调用index模板,并将模拟的数据传给该模板。
六、使用less美化页面
- 在app/assets目录中增加book-utils.less和book.less文件
- main.scala.html模板中加入
link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/book.css")">
本例中使用了两个less文件,均放入public --> sytlesheets 目录中
- book-utils.less——定义全局的变量和mixin
- book.less ——
其中book-utils.less
//VARs @bgColor: darken(#CCC, 25%); @baseColor: lighten(#122, 5%); //MIXINS .border-radius (@radius: 5px) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; } .box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) { box-shadow: @arguments; -moz-box-shadow: @arguments; -webkit-box-shadow: @arguments; }
book.less
@import "book-utils.less"; body { width: 960px; margin: auto; background-color: desaturate(lighten(@bgColor, 25%), 65%); border: 2px @bgColor solid; .border-radius; padding: 0px 15px; } h1 { color: saturate(@baseColor, 25%);} .date { h2 { border: 1px black dotted; .border-radius(100px); color: @baseColor; } .chat { .box-shadow(-2px, -3px, 2px, fade(spin(@bgColor, 15%), 30%)); h3 { border: 1px black solid; .border-radius; color: @baseColor } li.item span { width: 100px; display:inline-block;:first-child { color: lighten(@baseColor, 15%); } .time { color: saturate(@baseColor, 85%) } } } }