前言

对于习惯了 ASP.NET MVC Razor 模板引擎的人来说,比如我,一直在寻找前端 Javascript 端的 Razor 模板工具。这之前,我也了解到很多Javascript 端的模板工具,比如:jquery.tmplKnockoutfront.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 的模型类。

  1. public class Message
  2. {
  3. public Guid SenderKey { get; set; }
  4. public int SenderUserId { get; set; }
  5. public string SenderName { get; set; }
  6. public string Content { get; set; }
  7.  
  8. private DateTime _date { get; set; }
  9. public DateTime Date
  10. {
  11. get { return _date; }
  12. set
  13. {
  14. _date = value;
  15. _formattedDate = _date.ToLongDateString() + " " + _date.ToLongTimeString();
  16. }
  17. }
  18. private string _formattedDate;
  19. public string FormattedDate
  20. {
  21. get { return _formattedDate; }
  22. }
  23. }

2. 建立一个名为 MessageRepository 的数据访问类。

  1. public class MessageRepository
  2. {
  3. // 为了演示,不保存到数据库了
  4. private static readonly IList<Message> dbMessage = new List<Message>()
  5. {
  6. new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "张学友", Date = DateTime.Now, Content = "你好,请问今天星期几?" },
  7. new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "李世民", Date = DateTime.Now, Content = "今天真的很冷!" },
  8. new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "王大山", Date = DateTime.Now, Content = "吃早饭了么?" },
  9. new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "刘德华", Date = DateTime.Now, Content = "要不我们今晚去游泳吧?" },
  10. new Message{ SenderKey = Guid.NewGuid(), SenderUserId = , SenderName = "郭富城", Date = DateTime.Now, Content = "双手的温柔是你的错!" },
  11. };
  12.  
  13. public static IList<Message> GetAll()
  14. {
  15. return dbMessage;
  16. }
  17.  
  18. public static Message AddMessge(int senderUserId, string senderName, string content)
  19. {
  20. var message = new Message { SenderKey = Guid.NewGuid(), SenderUserId = senderUserId, SenderName = senderName, Date = DateTime.Now, Content = content };
  21. dbMessage.Add(message);
  22. return message;
  23. }
  24. }

为了演示,就增加了 2 个方法,一个得到所有的消息,另一个插入消息,不保存到数据库了。

3. 建立一个名为 SysConst 的系统常用的资源

  1. /// <summary>
  2. /// 系统常用的资源
  3. /// </summary>
  4. public class SysConst
  5. {
  6. /// <summary>
  7. /// 默认的发送者ID
  8. /// </summary>
  9. public static readonly int DefaultSenderUserId = ;
  10.  
  11. /// <summary>
  12. /// 默认的发送者姓名
  13. /// </summary>
  14. public static readonly string DefaultSenderUserName = "王大山";
  15. }

4. 建立 Default.aspx 页面或者 View.cshtml

首先在 Default.aspx.cs 页面中获取所有的消息,保存在 Messages 属性中,供 Default.aspx 页面调用。PS:没有用服务器控件,才出此策。

  1. public partial class Default : System.Web.UI.Page
  2. {
  3. /// <summary>
  4. /// 保存获取的消息集合,供页面调用
  5. /// </summary>
  6. protected IList<Message> Messages { get; private set; }
  7.  
  8. protected void Page_Load(object sender, EventArgs e)
  9. {
  10. if(!IsPostBack)
  11. {
  12. LoadData();// 调用加载数据的方法
  13. }
  14. }
  15.  
  16. /// <summary>
  17. /// 加载数据
  18. /// </summary>
  19. private void LoadData()
  20. {
  21. Messages = MessageRepository.GetAll();
  22. }
  23. }

5. 在页面引用 css 和 js

  1. <link href="css/bootstrap.min.css" rel="stylesheet" type="text/css" />
  2. <link href="css/chat.css" rel="stylesheet" type="text/css" />
  3. <script src="js/jquery-1.8.2.min.js" type="text/javascript"></script>
  4. <script src="js/kino.razor.min.js" type="text/javascript"></script>

6. 完成静态页面布局

效果图:

代码:

  1. <div id="chat">
  2. <div class="chat_content" style="height: 485px">
  3. <!-- 这里是需要循环的项 -->
  4. <script type="text/template" id="temp-message-gallery">
  5. @for(var i = 0; i < list.length; i++ )
  6. {
  7. <div class="@list[i].msgClass">
  8. <div class="chat_mes_title clearfix">
  9. <span class="date" style="display: inline">@list[i].message.FormattedDate</span>
  10. <span class="name" style="display: inline">@list[i].message.SenderName</span>
  11. </div>
  12. <div class="clear"></div>
  13. <div class="chat_mes_text clearfix">
  14. @list[i].message.Content
  15. </div>
  16. </div>
  17. }
  18. </script>
  19. </div>
  20. </div>
  21. <div class="chat_form">
  22. <form action="#">
  23. <button class="btn btn-success" type="button" id="sendmessage">
  24. 发送
  25. </button>
  26. <div class="chat_field">
  27. <textarea id="msg" placeholder="请输入消息"></textarea>
  28. </div>
  29. </form>
  30. </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 数组。

  1. <%
  2. int currentUserId = SysConst.DefaultSenderUserId; // 当前用户的 ID
  3. const string defaultClass = "chat_message"; // 默认样式
  4. const string mineClass = "chat_mes_my"; // 发送者是自己时的样式
  5. List<dynamic> list = new List<dynamic>();
  6. if (this.Messages != null && this.Messages.Count > )
  7. {
  8. foreach (var msg in this.Messages)
  9. {
  10. string msgClass = msg.SenderUserId == currentUserId ? defaultClass + " " + mineClass : defaultClass;
  11. // 上面是判断这条消息是否是当前登录用户发的,如果是,则添加一个样式
  12. list.Add(new { msgClass = msgClass, message = msg });
  13. }
  14. }
  15. string json = new JavaScriptSerializer().Serialize(list);
  16. %>

上面是为了展示历史消息,而做的。为了区分消息的发送者是否是自己,就自己新建了一个 dynamic 的集合,用来保存样式值、消息对象。最后把这个 dynamic 的集合序列化成 json,放到下一步(第 8 步)中。

8.  用 kino.razor 来呈现 json 集合

  1. <script type="text/javascript">
  2. // 显现所有消息的方法
  3. function renderAllMessage(dataArray)
  4. {
  5. var htmlTempl = $("#temp-message-gallery").html();// 找到模板
  6. var resultContent = kino.razor(htmlTempl, { list: dataArray });
  7. // 上面就是把 json 数组传递给 kino.razor。list 就是我们在模板
  8. // 中用到的变量名
  9. $(".chat_content").append(resultContent);// 找到容器 DIV,附加
  10. setScrollTop();
  11. }
  12. $(document).ready(function()
  13. {
  14. // 把当前服务器的消息实体集合序列化成 JSON,然后呈现。
  15. renderAllMessage(<%= json %>);
  16. });
  17. // 把滚动条设置到最下,以便呈现最新的消息。
  18. function setScrollTop()
  19. {
  20. var chatContent = $(".chat_content"); // 找到容器 DIV
  21. var scrollHeightValue = chatContent.get(0).scrollHeight;
  22. var heightValue = chatContent.height();// 得到容器的高度
  23. var scrollTopValue = scrollHeightValue - heightValue;
  24. chatContent.scrollTop(scrollTopValue);
  25. }
  26. </script>

注释都已经加上了,如果还不明白,请在评论里反馈,让笔者 知道,相互学习,谢谢!

做到这里,运行,就可以看到效果了。

9. 给 发送 按钮绑定点击事件

代码:

  1. <script type="text/javascript">
  2. $('#sendmessage').click(function ()
  3. {
  4. var content = $.trim($('#msg').val());
  5. if (content.length == 0)
  6. {
  7. alert("请输入消息!");
  8. return;
  9. }
  10. if (content.length > 1000)
  11. {
  12. alert("每次发送的消息不能超过 1000 字!");
  13. return;
  14. }
  15. $('#msg').attr("disabled", "disabled");
  16. $.ajax({
  17. type: "POST",
  18. url: "/post-message.ashx",
  19. data: { content: content },
  20. success: function (data)
  21. {
  22. // 返回成功后,调用呈现单条消息的方法
  23. renderSingleMessage(data);
  24. $('#msg').removeAttr("disabled").val('').focus();
  25. },
  26. error: function (msg)
  27. {
  28. alert("发送失败,请稍后再提交!");
  29. $('#msg').removeAttr("disabled").focus();
  30. }
  31. });
  32. });
  33. // 呈现单条消息
  34. function renderSingleMessage(msg)
  35. {
  36. var msgClass = '<%= defaultClass %>';
  37. var currentUserId = <%= currentUserId %>;
  38.  
  39. if (msg.SenderUserId == currentUserId)
  40. {
  41. msgClass += ' <%= mineClass %>';
  42. }
  43. var list = [];
  44. list[0] = { msgClass: msgClass, message: msg };
  45. renderAllMessage(list);// 调用呈现所有消息的方法
  46. }
  47. </script>

在 renderSingleMessage 中判断当前消息是否是本人添加的(目前发送者肯定是自己,后期会做成聊天室的形式,基于 ASP.NET SignalR 来做。),如果是,则什么样式,如果不是,则又是什么样式。最后把 json 对象传递给上面已经定义了的 renderAllMessage 函数用来呈现。

10. 在 ashx 保存消息

新建一个名为“post-message.ashx” 的一般处理程序,完成如下代码:

  1. public class post_message : IHttpHandler
  2. {
  3.  
  4. public void ProcessRequest(HttpContext context)
  5. {
  6. string content = context.Request.Form["content"];// 获取消息内容
  7.  
  8. var message = MessageRepository.AddMessge(SysConst.DefaultSenderUserId,
  9. SysConst.DefaultSenderUserName,
  10. content); // 保存消息
  11.  
  12. string json = new JavaScriptSerializer().Serialize(message);
  13.  
  14. context.Response.ContentType = "text/json";
  15. context.Response.Write(json);
  16. }
  17.  
  18. public bool IsReusable{get{return false;}}
  19. }

至此,流程已经走完。如果还不明白,请在评论里反馈,让笔者 知道,相互学习,谢谢!

总结

完整的流程如下:

oo1:

002:

003:

004:

也许你还会喜欢:

自定义 Javascript 模板规则,打造轻量级模板引擎

一个简单的 JavaScript 模板引擎

一个轻量级 Javascript 模板引擎 front.js【二】

谢谢浏览!

实例演示 kino.razor (前端 Javascript 模板工具,Razor 风格)的使用的更多相关文章

  1. 前端javascript模板

    doT.js——前端javascript模板引擎问题备忘录 我手里维护的一个项目,遇到一个问题:原项目的开发人员在Javascript中,大量的拼接HTML,导致代码极丑,极难维护.他们怎么能够忍受的 ...

  2. doT.js——前端javascript模板引擎问题备忘录

    我手里维护的一个项目,遇到一个问题:原项目的开发人员在Javascript中,大量的拼接HTML,导致代码极丑,极难维护.他们怎么能够忍受的了这么丑陋.拙劣的代码呢,也许是他们的忍受力极强,压根就没想 ...

  3. 【Juicer】 一个高效、轻量的前端 (Javascript) 模板引擎

    引用地址:http://juicer.name/docs/docs_zh_cn.html * 一个完整的例子 HTML 代码: <script id="tpl" type=& ...

  4. 用Razor来生成模板 using razor for template

    原文发布时间为:2011-09-15 -- 来源于本人的百度文章 [由搬家工具导入] http://razorengine.codeplex.com/

  5. JavaScript模板引擎实例应用

    在之前的一篇名为<移动端基于HTML模板和JSON数据的JavaScript交互>的文章中,我向大家说明了为什么要使用JavaScript模板以及如何使用,文末还提到了laytpl.art ...

  6. JavaScript模板引擎实例应用(转)

    本文将举实例向大家讲解几个常用模板引擎的简单使用. 演示地址:模板引擎示例http://demo.52fhy.com/jstemp/ 准备工作 演示数据:blog.json结构: { "li ...

  7. JavaScript模板引擎

    JavaScript模板引擎实例应用   在之前的一篇名为<移动端基于HTML模板和JSON数据的JavaScript交互>的文章中,我向大家说明了为什么要使用JavaScript模板以及 ...

  8. Handlebars的基本用法 Handlebars.js使用介绍 http://handlebarsjs.com/ Handlebars.js 模板引擎 javascript/jquery模板引擎——Handlebars初体验 handlebars.js 入门(1) 作为一名前端的你,必须掌握的模板引擎:Handlebars 前端数据模板handlebars与jquery整

    Handlebars的基本用法 使用Handlebars,你可以轻松创建语义化模板,Mustache模板和Handlebars是兼容的,所以你可以将Mustache导入Handlebars以使用 Ha ...

  9. MySQL基准测试(三)--开源工具与实例演示

    MySQL基准测试(三)--开源工具与实例演示 针对web应用 ab ab是一个Apache HTTP服务的基准测试工具. http_load http_load是一个针对Web服务器测试工具. JM ...

随机推荐

  1. 更新日志 - fir.im 回归,上线 Android Studio 插件

    上周 fir.im 经历了一场前所未有的挑战,因为自查应用网站暂停,在事情发生4天内我们完成了自查,fir.im 正式回归.煎熬的 98 个小时,感谢开发者与用户对我们的信任和支持. 使用注意: 禁止 ...

  2. Liferay7 BPM门户开发之35: AssetTag的集成查询

    Tag是liferay中的Asset特性,可以用来对信息进行分类,在iferay中的Asset类型为: 1. Web Content(自定义内容) 2. Documents and Media(文档库 ...

  3. iOS10之后openURL:方法过期之后的替代方法及使用

    目前苹果为iOS10开放了一个key:UIApplicationOpenURLOptionUniversalLinksOnly但亲测无效 目前使用的是这个key:UIApplicationOpenUR ...

  4. Struts2入门2 Struts2深入

    Struts2入门2 Struts2深入 链接: http://pan.baidu.com/s/1rdCDh 密码: sm5h 前言: 前面学习那一节,搞得我是在是太痛苦了.因为在Web项目中确实不知 ...

  5. 今日例子border

    border这个属性在页面上的使用率还是很高,例如我们需要理解的盒模型就需要对border有个 比较深的理解,如果你会盒模型,但对border没有深的理解,那只能说你只是知道盒模型,而 不是懂得盒模型 ...

  6. 连接SQL SERVER 2008需要加端口号

    VC2010 ADO 连接SQL SERVER 2008,127.0.0.1,1433,要加上端口,否则连不上.注意:地址和端口之间使用逗号隔开. 连接SQL SERVER 2000可以不加端口号,使 ...

  7. INFO - InstallShield中的InstallScript工程Setup.exe /s的使用细节

    在InstallShield的各种工程类型中,Basic MSI工程Build出的安装包基于Windows Installer标准,所以默认就支持静默安装(至于如何静默安装,请自行补充相关知识).而对 ...

  8. Linux驱动开发学习笔记(1):LINUX驱动版本的hello world

    1.关于目录    /lib/modules/2.6.9-42.ELsmp/build/   这个是内核源码所在的目录    一般使用这样的命令进入这个目录:cd /lib/modules/$(una ...

  9. Ques核心思想——CSS Namespace

    Facebook’s challenges are applicable to any very complex websites with many developers. Or any situa ...

  10. 连接的世界 - LTE时代产业趋势和战略分析

    连接的世界 - LTE时代产业趋势和战略分析 作者:华为有线技术公司李常伟 2014-09-22 信息产业发展解放的核心是这个世界连接的方式.由语音到数据.由通信到情感.由人的连接到物的连接.由“哑” ...