实例演示 kino.razor (前端 Javascript 模板工具,Razor 风格)的使用
前言
对于习惯了 ASP.NET MVC Razor 模板引擎的人来说,比如我,一直在寻找前端 Javascript 端的 Razor 模板工具。这之前,我也了解到很多Javascript 端的模板工具,比如:jquery.tmpl、Knockout、front.js 等等。园子里很多大牛推荐 Knockout,比如:蒋金楠(Artech)老师、汤姆大叔(TomXu)。个人觉得 Knockout 太强大了,强大到入门都是那么的困难,我看了官网上的几个例子,最后还是放弃了,觉得太复杂了,杀鸡还需要用牛刀吗?且并不是所有的“绑定”都要交给前端的,比如 Hello World 那个例子,FirstName、LastName、FullName 这些本该由服务器端直接输出的东西,何必又要交给 Knockout 呢。团队成员入门难就不适合了(PS:也许是我本人太笨,自黑一下,呵呵...)。在园子里搜了 kino.razor一下,正好还没有人来写文来介绍它,于是就有了本文。kino.razor 正如官方的介绍:
kino.razor - an easy to use,razor style javascript template tool
它是一个简单易用、Razor 风格的 Javascript 模板工具。用过之后感觉确实如此。
开始实战
1. 首先我们来建立一个名为 Message 的模型类。
public class Message
{
public Guid SenderKey { get; set; }
public int SenderUserId { get; set; }
public string SenderName { get; set; }
public string Content { get; set; } private DateTime _date { get; set; }
public DateTime Date
{
get { return _date; }
set
{
_date = value;
_formattedDate = _date.ToLongDateString() + " " + _date.ToLongTimeString();
}
}
private string _formattedDate;
public string FormattedDate
{
get { return _formattedDate; }
}
}
2. 建立一个名为 MessageRepository 的数据访问类。
public class MessageRepository
{
// 为了演示,不保存到数据库了
private static readonly IList<Message> dbMessage = new List<Message>()
{
new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "张学友", Date = DateTime.Now, Content = "你好,请问今天星期几?" },
new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "李世民", Date = DateTime.Now, Content = "今天真的很冷!" },
new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "王大山", Date = DateTime.Now, Content = "吃早饭了么?" },
new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "刘德华", Date = DateTime.Now, Content = "要不我们今晚去游泳吧?" },
new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "郭富城", Date = DateTime.Now, Content = "双手的温柔是你的错!" },
}; public static IList<Message> GetAll()
{
return dbMessage;
} public static Message AddMessge(int senderUserId, string senderName, string content)
{
var message = new Message { SenderKey = Guid.NewGuid(), SenderUserId = senderUserId, SenderName = senderName, Date = DateTime.Now, Content = content };
dbMessage.Add(message);
return message;
}
}
为了演示,就增加了 2 个方法,一个得到所有的消息,另一个插入消息,不保存到数据库了。
3. 建立一个名为 SysConst 的系统常用的资源
/// <summary>
/// 系统常用的资源
/// </summary>
public class SysConst
{
/// <summary>
/// 默认的发送者ID
/// </summary>
public static readonly int DefaultSenderUserId = ; /// <summary>
/// 默认的发送者姓名
/// </summary>
public static readonly string DefaultSenderUserName = "王大山";
}
4. 建立 Default.aspx 页面或者 View.cshtml
首先在 Default.aspx.cs 页面中获取所有的消息,保存在 Messages 属性中,供 Default.aspx 页面调用。PS:没有用服务器控件,才出此策。
public partial class Default : System.Web.UI.Page
{
/// <summary>
/// 保存获取的消息集合,供页面调用
/// </summary>
protected IList<Message> Messages { get; private set; } protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
LoadData();// 调用加载数据的方法
}
} /// <summary>
/// 加载数据
/// </summary>
private void LoadData()
{
Messages = MessageRepository.GetAll();
}
}
5. 在页面引用 css 和 js
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="css/chat.css" rel="stylesheet" type="text/css" />
<script src="js/jquery-1.8.2.min.js" type="text/javascript"></script>
<script src="js/kino.razor.min.js" type="text/javascript"></script>
6. 完成静态页面布局
效果图:

代码:
<div id="chat">
<div class="chat_content" style="height: 485px">
<!-- 这里是需要循环的项 -->
<script type="text/template" id="temp-message-gallery">
@for(var i = 0; i < list.length; i++ )
{
<div class="@list[i].msgClass">
<div class="chat_mes_title clearfix">
<span class="date" style="display: inline">@list[i].message.FormattedDate</span>
<span class="name" style="display: inline">@list[i].message.SenderName</span>
</div>
<div class="clear"></div>
<div class="chat_mes_text clearfix">
@list[i].message.Content
</div>
</div>
}
</script>
</div>
</div>
<div class="chat_form">
<form action="#">
<button class="btn btn-success" type="button" id="sendmessage">
发送
</button>
<div class="chat_field">
<textarea id="msg" placeholder="请输入消息"></textarea>
</div>
</form>
</div>
不知道大家注意到那段注释“这里是需要循环的项”下面的代码没有,是不是很熟悉,很爽?千万不要以为这是用 ASP.NET MVC Razor 写的服务器端代码,呵呵,这就是按照 kino.razor 模板的规则来写的,是客户端代码!!!!!!
其中 @list[i].msgClass 是样式输出,判断这条消息是否是当前登录用户发的,如果不是,样式就是“chat_message”。如果是,样式就是“chat_message chat_mes_my”。
其中 @list[i].message 就是我们定义的 Message 模型类对应的 json 对象。
7. 把后台 Default.aspx.cs 传递过来的 List<Message> 序列化成 json 数组。
<%
int currentUserId = SysConst.DefaultSenderUserId; // 当前用户的 ID
const string defaultClass = "chat_message"; // 默认样式
const string mineClass = "chat_mes_my"; // 发送者是自己时的样式
List<dynamic> list = new List<dynamic>();
if (this.Messages != null && this.Messages.Count > )
{
foreach (var msg in this.Messages)
{
string msgClass = msg.SenderUserId == currentUserId ? defaultClass + " " + mineClass : defaultClass;
// 上面是判断这条消息是否是当前登录用户发的,如果是,则添加一个样式
list.Add(new { msgClass = msgClass, message = msg });
}
}
string json = new JavaScriptSerializer().Serialize(list);
%>
上面是为了展示历史消息,而做的。为了区分消息的发送者是否是自己,就自己新建了一个 dynamic 的集合,用来保存样式值、消息对象。最后把这个 dynamic 的集合序列化成 json,放到下一步(第 8 步)中。
8. 用 kino.razor 来呈现 json 集合
<script type="text/javascript">
// 显现所有消息的方法
function renderAllMessage(dataArray)
{
var htmlTempl = $("#temp-message-gallery").html();// 找到模板
var resultContent = kino.razor(htmlTempl, { list: dataArray });
// 上面就是把 json 数组传递给 kino.razor。list 就是我们在模板
// 中用到的变量名
$(".chat_content").append(resultContent);// 找到容器 DIV,附加
setScrollTop();
}
$(document).ready(function()
{
// 把当前服务器的消息实体集合序列化成 JSON,然后呈现。
renderAllMessage(<%= json %>);
});
// 把滚动条设置到最下,以便呈现最新的消息。
function setScrollTop()
{
var chatContent = $(".chat_content"); // 找到容器 DIV
var scrollHeightValue = chatContent.get(0).scrollHeight;
var heightValue = chatContent.height();// 得到容器的高度
var scrollTopValue = scrollHeightValue - heightValue;
chatContent.scrollTop(scrollTopValue);
}
</script>
注释都已经加上了,如果还不明白,请在评论里反馈,让笔者 知道,相互学习,谢谢!
做到这里,运行,就可以看到效果了。

9. 给 发送 按钮绑定点击事件
代码:
<script type="text/javascript">
$('#sendmessage').click(function ()
{
var content = $.trim($('#msg').val());
if (content.length == 0)
{
alert("请输入消息!");
return;
}
if (content.length > 1000)
{
alert("每次发送的消息不能超过 1000 字!");
return;
}
$('#msg').attr("disabled", "disabled");
$.ajax({
type: "POST",
url: "/post-message.ashx",
data: { content: content },
success: function (data)
{
// 返回成功后,调用呈现单条消息的方法
renderSingleMessage(data);
$('#msg').removeAttr("disabled").val('').focus();
},
error: function (msg)
{
alert("发送失败,请稍后再提交!");
$('#msg').removeAttr("disabled").focus();
}
});
});
// 呈现单条消息
function renderSingleMessage(msg)
{
var msgClass = '<%= defaultClass %>';
var currentUserId = <%= currentUserId %>; if (msg.SenderUserId == currentUserId)
{
msgClass += ' <%= mineClass %>';
}
var list = [];
list[0] = { msgClass: msgClass, message: msg };
renderAllMessage(list);// 调用呈现所有消息的方法
}
</script>
在 renderSingleMessage 中判断当前消息是否是本人添加的(目前发送者肯定是自己,后期会做成聊天室的形式,基于 ASP.NET SignalR 来做。),如果是,则什么样式,如果不是,则又是什么样式。最后把 json 对象传递给上面已经定义了的 renderAllMessage 函数用来呈现。
10. 在 ashx 保存消息
新建一个名为“post-message.ashx” 的一般处理程序,完成如下代码:
public class post_message : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
string content = context.Request.Form["content"];// 获取消息内容 var message = MessageRepository.AddMessge(SysConst.DefaultSenderUserId,
SysConst.DefaultSenderUserName,
content); // 保存消息 string json = new JavaScriptSerializer().Serialize(message); context.Response.ContentType = "text/json";
context.Response.Write(json);
} public bool IsReusable{get{return false;}}
}
至此,流程已经走完。如果还不明白,请在评论里反馈,让笔者 知道,相互学习,谢谢!
总结
完整的流程如下:
oo1:

002:

003:

004:

也许你还会喜欢:
一个轻量级 Javascript 模板引擎 front.js【二】
谢谢浏览!
实例演示 kino.razor (前端 Javascript 模板工具,Razor 风格)的使用的更多相关文章
- 前端javascript模板
doT.js——前端javascript模板引擎问题备忘录 我手里维护的一个项目,遇到一个问题:原项目的开发人员在Javascript中,大量的拼接HTML,导致代码极丑,极难维护.他们怎么能够忍受的 ...
- doT.js——前端javascript模板引擎问题备忘录
我手里维护的一个项目,遇到一个问题:原项目的开发人员在Javascript中,大量的拼接HTML,导致代码极丑,极难维护.他们怎么能够忍受的了这么丑陋.拙劣的代码呢,也许是他们的忍受力极强,压根就没想 ...
- 【Juicer】 一个高效、轻量的前端 (Javascript) 模板引擎
引用地址:http://juicer.name/docs/docs_zh_cn.html * 一个完整的例子 HTML 代码: <script id="tpl" type=& ...
- 用Razor来生成模板 using razor for template
原文发布时间为:2011-09-15 -- 来源于本人的百度文章 [由搬家工具导入] http://razorengine.codeplex.com/
- JavaScript模板引擎实例应用
在之前的一篇名为<移动端基于HTML模板和JSON数据的JavaScript交互>的文章中,我向大家说明了为什么要使用JavaScript模板以及如何使用,文末还提到了laytpl.art ...
- JavaScript模板引擎实例应用(转)
本文将举实例向大家讲解几个常用模板引擎的简单使用. 演示地址:模板引擎示例http://demo.52fhy.com/jstemp/ 准备工作 演示数据:blog.json结构: { "li ...
- JavaScript模板引擎
JavaScript模板引擎实例应用 在之前的一篇名为<移动端基于HTML模板和JSON数据的JavaScript交互>的文章中,我向大家说明了为什么要使用JavaScript模板以及 ...
- Handlebars的基本用法 Handlebars.js使用介绍 http://handlebarsjs.com/ Handlebars.js 模板引擎 javascript/jquery模板引擎——Handlebars初体验 handlebars.js 入门(1) 作为一名前端的你,必须掌握的模板引擎:Handlebars 前端数据模板handlebars与jquery整
Handlebars的基本用法 使用Handlebars,你可以轻松创建语义化模板,Mustache模板和Handlebars是兼容的,所以你可以将Mustache导入Handlebars以使用 Ha ...
- MySQL基准测试(三)--开源工具与实例演示
MySQL基准测试(三)--开源工具与实例演示 针对web应用 ab ab是一个Apache HTTP服务的基准测试工具. http_load http_load是一个针对Web服务器测试工具. JM ...
随机推荐
- 【转】Oracle 执行动态语句
1.静态SQLSQL与动态SQL Oracle编译PL/SQL程序块分为两个种:其一为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型:另外一 ...
- iOS开发---集成百度地图,位置偏移问题
iOS 集成百度SDK 请参考 百度地图官方文档 ,这里不就多啰嗦了 本文介绍的是在百度地图上根据经纬度,自定义气泡时,气泡位置的偏移,在我们天朝这种事是很常见的,也见怪不怪了,在项目中使用的百度地图 ...
- Python:将utf-8格式的文件转换成gbk格式的文件
需求:将utf-8格式的文件转换成gbk格式的文件 实现代码如下: def ReadFile(filePath,encoding="utf-8"): with codecs.ope ...
- iPhone开发视频教程 Objective-C部分 (51课时)
第一.二章 OC基础语法 iPhone开发教程 第一章 OC基础语法 iPhone开发概述-必看(1.1)http://www.apkbus.com/android-102215-1-1.html ...
- Ubuntu虚拟机JeOS安装-2016.08.28
根据官网的说明JeOS的镜像已经在官方不发行了,所以你在别的帖子里看到的安装jeos的镜像地址已经不适用了. 那么应该如何安装这种最小版本的linux操作系统呢? 其一,如果想要安装老版本的jeos系 ...
- php加密解密功能类
这两天突发奇想想要用php写一个对日常项目加密以及解密的功能,经过努力简单的封装了一个对php代码进行加密解密的类,一些思想也是来自于网络,初步测试用着还行,可以实现对指定项目的加密以及解密(只针对本 ...
- 成功在神舟K650c-i7 d2(i7-4700MQ、HM87)上装好了Windows XP
成功在神舟K650c-i7 d2(i7-4700MQ.HM87)上装好了Windows XP 本来已经在K650c上装好了Windows7.Windows8双系统,奈何某些旧软件只能在Windows ...
- 搞不清FastCgi与PHP-fpm之间是个什么样的关系(转载)
刚开始对这个问题我也挺纠结的,看了<HTTP权威指南>后,感觉清晰了不少. 首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者. ...
- [玩转微信平台]XML的格式化- 如何去掉XML 文档头和命名空间
前言 系统要求能够回复微信用户发过来的文本消息.实现中使用的实体对象进行XML的序列化的方式来实现XML消息. 微信平台的回复例子 http://mp.weixin.qq.com/wiki/14/ ...
- .net微信公众号开发——快速入门
作者:王先荣 最近在学习微信公众号开发,将学习的成果做成了一个类库,方便重复使用. 现在微信公众号多如牛毛,开发微信的高手可以直接无视这个系列的文章了. 使用该类库的流程及寥寥数行代码得到的结果如下. ...