本文主要记录 JsRender模板 的使用
- 表结构
- 界面样式
- 让div可拖拽
- 数据绑定
- 使用模板 JsRender
- Controller代码
其实实现div拖拽利用jQueryUI做很简单,呵呵,本文主要介绍怎么使用 JsRender 做模板
表结构
CREATE TABLE [dbo].[MyNote](
[ID] [int] IDENTITY(1,1) NOT NULL, --编号
[NContent] [varchar](max) NOT NULL, --留言内容
[IP] [varchar](50) NULL, --发布者IP
[Date] [datetime] NOT NULL, --留言时间
CONSTRAINT [PK_MyNote] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
界面样式和div
<style>
.draggable {
width: 200px;
height: 150px;
padding: 0.5em;
float: left;
margin: 0 10px 10px 0;
border: 1px solid #ccc;
background: #fafafa;
position: relative;
}
.draggable .title {
cursor: move;
padding: 5px;
background: #ccc;
color: #fff;
}
.draggable .date {
position: absolute;
left: 15px;
bottom: 5px;
}
</style>
<div class="contentbox" id="containment-wrapper" style="height: 100%;">
<div class="draggable">
<div class="title">title</div>
内容
<div class="date">2013-05-01</div>
</div>
</div>
如何让div可以拖动
先利用jQueryUI的draggable方法让我们的div可以拖拽,详细请看:http://jqueryui.com/draggable/,代码:
//让div可以拖拽
$(".draggable").draggable({
containment: "#containment-wrapper", scroll: false,
start: function (e, ui) {
$(".draggable").zIndex("");
$(this).zIndex(1000);
}
});
//阻止文本被选中
$(".contentcontainer").disableSelection();
这里在拖拽的事件中增加了一个 start,所有小纸条的zIndex等于空,然后在对当前拖拽的div增加到最上层,这样防止拖拽时被其他div遮挡
containment 的参数是让所有小纸条在制定的div内部
数据绑定
最后考虑怎么绑定数据,可以用mvc的机制,代码如下:
<div class="contentbox" id="containment-wrapper" style="height: 100%;">
@foreach (var item in Model)
{
<div class="draggable">
<div class="title">title</div>
@item.NContent
<div class="date">@item.Date</div>
</div>
}
</div>
View Code
但是这样不友好,我需要用无刷新的方式来实现,但是通常我们做法是字符串拼接来生成一个html的字符串
$.post("@Url.Action("NoteList")", function (data) {
var html = "";
$(data).each(function (index, e) {
html += "<div class='draggable'><div class='title'>title</div>" + e.NContent + "......";
});
},"json");
这样代码不好维护,使用也不方便,所以我们可以使用 jQuery模板来实现,其实网上有很多种,我找了一个叫 JsRender 的,
使用JsRender模板
下面来看看代码 ,先需要定义个模板,看看代码是不是简单清晰多了,呵呵
<script src="~/Scripts/jsrender.js"></script>
<script id="Template" type="text/x-jsrender">
<div class="draggable" style="top: {{attr: top}}px; left: {{attr:left }}px;">
<div class="title">NO:{{:#index+1}}</div>
{{:NContent}}
<div class="date">{{:Date}}</div>
</div>
</script>
用{{:变量}}或{{>变量}}来显示数据 ,: 和 >的区别在于 转义html, : 会直接显示包括html代码,>是会将html转义
{{attr:变量}}表示这是属性值,其实还有很多方法,大家可以去官网看看,例如 if for 等等
这里的 {{attr:top}} Visual Studio 会提示警告,但是并不影响我们的模板
再来看看绑定的代码,就这么一句话,直接把json的数据传给模板就能生成了
$.post("@Url.Action("NoteList")", function (data) {
$("#containment-wrapper").html($("#Template").render(data));
},"json");
Controller 代码
前端的代码就写完了,再来看看 Controller 的代码
/// <summary>
/// 获取留言列表
/// </summary>
/// <returns></returns>
public ActionResult NoteList()
{
//获取留言前100条
var list = db.MyNote.OrderByDescending(o => o.Date).Take(100).ToList();
int count = list.Count;
List<object> pos = new List<object>();
Random ra = new Random();
//生成每个div随机偏移坐标,打乱div的位置
var top = Enumerable.Range(1, count).Select(s => ra.Next(-20, 30)).ToList();
var left = Enumerable.Range(1, count).Select(s => ra.Next(-20, 30)).ToList();
//增加到集合
for (int i = 0; i < count; i++)
{
pos.Add(new { top = top[i], left = left[i], NContent = list[i].NContent, Date = list[i].Date });
}
return JsonDate(pos);
//return Json(pos, JsonRequestBehavior.AllowGet);
}
这里有两点需要注意,
1.top和left变量,在循环或大量需要调用linq的时候,一定要使用ToList()方法存储到变量中,不要在使用时去ToList(),在循环内部去ToList()效率会非常低,之前吃过亏,呵呵
2.MVC中Controller的Json方法返回带时间的数据时,格式会变成 "\/Date(1369419656217)\/" 这样的,这里的 JsonDate 方法请看我的这个帖子:
好了,写完了,有什么不对的地方希望大家提出来哦