前端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 ...
随机推荐
- Code First 数据注释--InverseProperty 和 ForeignKey
ForeignKey 按照约定在Post类中看到BlogId属性,会认为是Blog类的外键,但是在Blog类中并没有BlogId属性,解决方法是,在 Post 中创建一个导航属性,并使用 Foreig ...
- AVD启动不了 ANDROID_SDK_HOME is defined but could not find *.ini
报错提示______________________________________________________________________ Starting emulator for AVD ...
- SQL Server 创建链接服务器
遇到下列问题: 线上服务器A,中转服务器B,本地服务器C 数据在A上面,想在B上面操作类似 select * from [A].[database].table这样的SQL,不用去链接服务器,直接把处 ...
- 未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序
运行时出现了错误,提示未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序. 这个问题的原因是64位PC上安装了Office的32位版本,所以Micro ...
- hprof教程
大部分内容参考http://www.linuxidc.com/Linux/2012-04/58178.htm J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profili ...
- jquery.BannerRotator.js
项目地址:https://github.com/snipertulip/BannerRotator 演示地址:http://snipertulip.github.io/BannerRotator/de ...
- PHP Warning: phpinfo(): It is not safe to rely on the system's timezone setting
错误描述: PHP Warning: phpinfo(): It is not safe to rely on the system's timezone settings. You are *re ...
- 简单的使用php多线程抓取网页
PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Cu ...
- Oracle 中包的应用
包由两个分离的部分组成:包头(PACKAGE)和包体(PACKAGEBODY).包头是包的说明部分,是对外的操作接口,对应用是可见的;包体是包的代码和实现部分,对应用来说是不可见的黑盒. ...
- 使用 C# 编写简易 ASP.NET Web 服务器
原文 http://www.cnblogs.com/lcomplete/p/use-csharp-write-aspnet-web-server.html 如果你想获得更好的阅读体验,可以前往我在 g ...