前端JS模版库kino.razor - 原理流程分析 - 改进版轮子RazorJs
1.前言
从后台获取数据,在前端JS里面拼接字符串,不累吗?敢不敢找一款前端使使。。。
现在这种模板库比较多了,我用过的jquery-template 、JsRender 、听说过的一堆,还有各种MVC库里面带的各种模板库,之前看到有人介绍kino.razor这个,一看源代码,就几百行,以前用过的那些template engine,好奇怎么出来的。就借这个机会研究研究,自己模仿者造一个。它源码少啊。。。
2.kino.razor模版库原理,流程分析
怎么使用http://www.cnblogs.com/Music/p/kino-razor.html这篇里有介绍 , 前台模板写成
<script type="text/template">
@{
//code block...
var data=10;
} @for(var i=10;i<data;i++)
{
<div>@(i)</div>
}
</script>
这种js代码与html混在一起的,是怎么实现的呢。。。
首先分析这种template要认识到,有两种模式,即js code 模式,和 html代码模式。在code模式中,@{ code block}这种,就是要执行的代码,不会产生模版生成的内容,另一种就是引用变量了,在<div>@(variable)</div>这里,这个@(variable)同<div> </div>一样,会被生成到 模板引擎 生成的html中。这么说有点抽象。所以说,有三种状态1.代码块 2.普通string,最后生成到html 3.变量,需要执行并申城到html里
在拿到templateString之后,模板引擎会一个字一个字的扫描,处理,碰到@{}这样的代码块,它就需要在一个context中执行,以保存其中的变量呢,碰到普通的string,像<div>这种,直接放到结果集中,对于@(variable)需要在这个context中解释一下,这个值说不定就是前面code block中声明的,再放到结果集中。
就像这样一个 模板,可以使用kino.razor(template,model);这个model对象是传进去的,要被模板利用,就同样需要这样的context,那么谁来提供这样一个context呢???我是看了源码,这个模板字符串最终会被编译成一个函数,就是var func=某种方法(string template),将string变成一个function,然后这个model,传给func,即func(model)就会得到输出的html

编译出的函数会是啥样
function func(model){
var result=[];
//在@{}这样的code block中全是code,直接放到 这里运行
var data=10;
//@for(){ }
在for while循环里面默认是String模式,就是可以直接写<div>引用变量要写@符号
for(var i=0;i<10;i++)
{
//在循环内部,String 输出内容,我们构建一个数组result 来装 要生成的内容
//碰到<div>
result.push("<div>");
//碰到@(i)
result.push(i);//变量,在当前context取值,并放到生成结果集中
//碰到</div>,放到result
result.push("</div>")
}
}
这样就达到了循环的目的。可是这样的期望函数咋生成???JS里面有 new Function(parameter0,...parametern,最后一个参数为函数体)
我们只要能生成函数体就可以了。生成那个函数体functionContent,以字符串形式呈现,需要我们根据template string的状态,是code block,还是string,还是变量variable,往functionContent添加不同的语句,最后构成函数func,调用func(model)就返回了我们函数体中的result。在kino.razor中用SegmentHelper.parse将templateString转化为一个一个segmrnt,

这个segment就是以状态区分的内容,content 即内容,type 即类型,状态
用ContentHelper将这个segment数组,转变成functionContent,进而返回一个参数为model的func。
That‘s all。
3.RazorJs.js
搞清楚那个库的原理,和流程,自己写一个也就不是太难,模仿照着做就行。我自己捣鼓着做了一个RazorJs,将能简化的简化,我不想要的功能就没做,例如kino.razor中@variable是可行的,即不加小括号'()'也可以,我就觉得不直观,就没有实现。在这个RazorJs中引用变量必须要用小括号括起来,如@(variable),添加了一些和jquery相关的方法,当然在没有jquery的情况下也是可以使用razor.render 和 compile方法。修改model为ViewBag。第一遍源码跟kino.razor太像,而且写完第二天,发现支持的while循环没有意义,不支持在while内部写code block例如while(i>0) i--;这个i--没地写,故重新整理思路,重新写了份,原来的更名RazorJs.0.1.js。
添加类似angularJS的ng-repeat的直接使用div作为模板的方法
例如直接在div中写
<div razor-template razor-for="var i = 0;i<10; i++">
other template ....
</div>
使用$(selector).renderNode(ViewBag)来使render,并show出来,写上了razor-template在dom ready的时候会被隐藏
另外一种
<div razor-repeat="item in items" razor-template>
<div>@item.age</div>
</div>
这种跟C#里面写的foreach(var item in items)是一致的,这种div使用$(selector).renderRepeat(ViewBag),来使模板变为字符串
还有更多的扩展用法可以看csdn code 地址https://code.csdn.net/magicdawn/razorjs。那些markdown正在慢慢的写。源码注释超级多,别见怪。
4.关于渲染速度...
在上面我们知道,这些其实是编译成了一个函数 , 所以在那些测试中所谓的千次万次render是没有意义的,真正的次数多的render,可以先compile出来func函数,再自己调用func(ViewBag),而生成这个函数的速度,都是线性扫描,不见得能快到哪里去,所以不用担心这个。
前端JS模版库kino.razor - 原理流程分析 - 改进版轮子RazorJs的更多相关文章
- 【超精简JS模版库/前端模板库】原理简析 和 XSS防范
使用jsp.php.asp或者后来的struts等等的朋友,不一定知道什么是模版,但一定很清楚这样的开发方式: <div class="m-carousel"> < ...
- 前端js模版 预编译工具Tmod js使用入门
1. 安装node js , 2. 用 npm install -g tmodjs 命令安装tmod 3.了解参数配置 4.运行测试例子->命令窗切换到当前文档位置 --->执行tomd ...
- 前端js模板库 JinkoTemplate
有时候需要使用ajax来异步生成html,最土的方法就是用js的‘+’连接html代码,生成繁琐.一旦需要修改,对于少量的html代码到没啥问题,要是比较复杂的样式时,就真坑爹了,眼花缭乱有木有?Ji ...
- Web前端JS实现轮播图原理
实现轮播图有很多方式,但是html的结构都是一样的.本文使用了Jquery框架,Dom操作更加方便灵活 html部分: <div class="banner"> < ...
- 单点登录 sso -- cas CAS 原理 流程 分析
Yelu大学研发的CAS(Central Authentication Server) 下面就以耶鲁大学研发的CAS为分析依据,分析其工作原理.首先看一下最上层的项目部署图: 部署项目时需要部署一个独 ...
- js下载文件方法与原理小分析
原理:html的a标签,设置dawnload属性后,可以下载href指向的文件. 在js中往往是点击某一个按钮后下载一个文件,并且文件的地址是变化的.因此我们可以动态创建一个a标签,设置好downlo ...
- 实例演示 kino.razor (前端 Javascript 模板工具,Razor 风格)的使用
前言 对于习惯了 ASP.NET MVC Razor 模板引擎的人来说,比如我,一直在寻找前端 Javascript 端的 Razor 模板工具.这之前,我也了解到很多Javascript 端的模板工 ...
- js 模版加载到前端
js 模版加载到前端 简单有效不高端 配个路由 /js/:filename , 用 readTemplate 响应请求,前端可以按模块方式直接 require 模板 'use strict' var ...
- Atitit。Tree文件解析器的原理流程与设计实现 java c# php js
Atitit.Tree文件解析器的原理流程与设计实现 java c# php js 1. 解析原理与流程1 1.1. 判断目录 ,表示服 dirFlagChar = "└├─&quo ...
随机推荐
- python - socket模块1
1.使用生活中的接打电话,解释socket通信流程 2.根据上图,写出socket通信的伪代码 2.1.server端伪代码 #买手机 #买手机卡 #开机 #等待电话 #收消息 #发消息 #挂电 ...
- .NET基础拾遗(5)反射2
本篇是学习反射的一个应用小场景而做的学习笔记,主要是一个小的总结,并对各个步骤的记录,以便将来回顾. 一.基础框架-敏捷基础版本 这里假定我们要开发一个记事本,选择Windows Form技术开发,界 ...
- 拉姆达表达式(Lambda Expressions)
上面两种写法是一样的 ,拉姆达表达式也是一种委托, 但引用的是匿名方法
- java Math.random()随机数的产生
Math.random()是java内置产生随机数的函数,Math.random()能够产生[0,1)的浮点数,当我们要产生特定范围的数时,可以采用如下办法: 1.Math.random()*(最大数 ...
- shell中的循环语句
for语法格式 for var in list;do commands done 其中list可以包含: 1) 直接写 for alpha in a b c d;do echo $alpha done ...
- 【Python学习】指定两点地理位置经纬度的距离计算
指定两点地理位置经纬度的距离计算 #coding=utf-8 from math import * # input Lat_A 纬度A # input Lng_A 经度A # input Lat_B ...
- HDU 5492(DP) Find a path
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5492 题目大意是有一个矩阵,从左上角走到右下角,每次能向右或者向下,把经过的数字记下来,找出一条路径是 ...
- nodejs+express Mvc站点
nodejs+express Mvc站点 像asp.net Mvc一样开发nodejs+express Mvc站点 首先,我是个c#码农.从事Mvc开发已然4个年头了,这两年前端MVC的兴起,我也跟风 ...
- Oracle case用法
1:update 时做检查使用update mw_contract set payTimes=( case else payTimes end )'; 2:select时使用 select case ...
- Powershell变量的类型和强类型
Powershell变量的类型和强类型12 12月, 2011 在 Powershell tagged Powershell教程 / 变量 / 存储 / 数据 / 类型 by Mooser Lee ...