zoukankan      html  css  js  c++  java
  • 实例演示 kino.razor (前端 Javascript 模板工具,Razor 风格)的使用

    前言

    对于习惯了 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 的模型类。

    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 = 1, SenderName = "张学友", Date = DateTime.Now, Content = "你好,请问今天星期几?" },
            new Message{ SenderKey = Guid.NewGuid(), SenderUserId = 2, SenderName = "李世民", Date = DateTime.Now, Content = "今天真的很冷!" },
            new Message{ SenderKey = Guid.NewGuid(), SenderUserId = 3, SenderName = "王大山", Date = DateTime.Now, Content = "吃早饭了么?" },
            new Message{ SenderKey = Guid.NewGuid(), SenderUserId = 4, SenderName = "刘德华", Date = DateTime.Now, Content = "要不我们今晚去游泳吧?" },
            new Message{ SenderKey = Guid.NewGuid(), SenderUserId = 5, 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 = 3;
    
        /// <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 > 0)
        {
            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 模板规则,打造轻量级模板引擎

    一个简单的 JavaScript 模板引擎

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

    谢谢浏览!

  • 相关阅读:
    vue part1 基础
    【转载】NBU异机恢复oracle
    【转载】跨域请求
    [转载] django contenttypes
    rest_framework setting
    rest_framework 视图/路由/渲染器/认证授权/节流
    【转载整理】 mysql百万级数据库分页性能
    rest_framework 分页
    rest_framework 序列化
    django middleware
  • 原文地址:https://www.cnblogs.com/Music/p/kino-razor.html
Copyright © 2011-2022 走看看