上一篇最后提到了模板,并尝试自己编写一个最简单版本;有些朋友可能用过 jqtmpl,这是一个基于jquery的模板引擎,不过它已经不再更新了,而且据说渲染速度比较慢。这里介绍另外一个模板引擎:jsRender。个人觉得这些东西学习起来还是很简单的,挑一个看看就行,实际要用到了哪个,官网看看demo也就会用了。之所以选择jsRender,因为它具有以下特点:

  • 简单直观
  • 功能强大
  • 可扩展的
  • 快如闪电

  当然,谁都会自己给自己的产品下这样定义。不过我用完后,确实发现它:简单直观、功能强大、扩展性强;至于快如闪电...,有兴趣的朋友可以测试看看有多快!接下来就让我们学习jsRender的运用,这里用的是1.0版本。

一、基础

  jsRender 三个最重要的概念:模板、容器和数据。最重要的是:view(视图) 是我们定义的模板,上下文是视图所用的对象。

  先来看一下模板的基本标签:{{:}} 和 {{>}}(或{{html:}})。两者都可以输出内容,不过后者是经过html编码的。jsRender有几种方式可以渲染数据:

  假设模板如下:

<script type="text/tmp" id="tmp1">
<p>my name is: {{:name}}</p>
<p>i am: {{:info.age}} years old</p>
</script>

  数据如下:  

    var data = {
name : "tom",
info : {age : 19}
}

  1.无编译前渲染。直接指定模板。例子:

    var html = $("#tmp1").render(data);
        console.log(html);

  2.编译后渲染。指定模板或字符串。

    2.1 指定模板。效果同1。例子:

      var template = $.templates("#tmp1");
      var html = template.render(data);
      console.log(html);

    2.2 指定模板名称

      2.2.1 传递字符串

        var template = $.templates("tmp1","<b>{{:name}}</b>");
            var html = $.render.tmp1(data);
            console.log(html);

      2.2.2 传递多个模板名称

        var template = $.templates({
            "tmp1":$("#tmp1").html(),
            "tmp2":$("#tmp2").html()
           });
          var html = $.render.tmp1(data);    
          console.log(html);

二、逻辑判断和循环

  2.1 if-else

  语法:{{if condition}} ... {else condition} ... {{else}}... {{/if}}

  注意这里是 if-else-else,而不是 if-else if-else。例子:  

<script type="text/tmp" id="tmp4">
<p>my name is: {{:name}}</p>
<p>我是:
{{if info.age >= 18}}
成年人
{{else}}
未成年
{{/if}}
</p>
</script>
var html = $("#tmp4").render(data);
$("#list").html(html);

  2.2 for

  语法:{{for}} ... {{/for}}

  2.2.1 简单for。例子:  

    <script type="text/tmp" id="tmp5">
{{for}}
<li>id:{{:ID}} name:{{:Name}}</li>
{{/for}}
</script>
var arr = [
{ ID: 1, Name: "tom" },
{ ID: 2, Name: "jack" },
{ ID: 3, Name: "lucy"}
];
var html = $("#tmp5").render(arr);
$("#list").html(html);

  2.2.2 嵌套for。

  语法:{{for}}...{{for 当前上下文}} ... {{/for}} ... {{/for}}

  被嵌套的for 可以指定要遍历的属性的名称。#getIndex() 和 #data 会在下面提到。例子:  

<script type="text/tmp" id="tmp7">
{{for}}
<li>
name:{{:name}}
<ul>
{{for hobbies}}
<li>{{:#getIndex() + 1}}:{{:#data}}</li>
{{/for}}
</ul>
</li>
{{/for}}
</script>
arr = [
{ name: "tom", hobbies: ["篮球", "足球"] },
{ name: "jack", hobbies: ["篮球", "橄榄球"] },
{ name: "lucy", hobbies: ["游泳", "羽毛球"] }
];
var html = $("#tmp7").render(arr);
$("#list").html(html);

  2.2.3 分离for。

  语法:{{for 上下文 tmpl="模板id" /}}

  如果for的逻辑比较复杂,嵌套的for就会让我们的模板变得复杂,维护难度加大;我们可以将for分离,以上面的例子,可以将for放到一个新的模板,然后通过 tmpl属性指定。例子:

<script type="text/tmp" id="tmp8">
{{for}}
<li>
name:{{:name}}
<ul>
{{for hobbies tmpl="#tmp9" /}}
</ul>
</li>
{{/for}}
</script>
<script type="text/tmp" id="tmp9">
<li>{{:#getIndex() + 1}}:{{:#data}}</li>
</script>
var html = $("#tmp8").render(arr);
$("#list").html(html);

三、#data、#index、#parent

  开始提到,我们定义的模板就是视图,用到的对象就是上下文。

  #data 当前的上下文,有时候它是很有用的,例如我们返回的是最简单的数组[1,2,3,4],这时没法通过{{:属性}} 的形式去获得,通过{{#data}}即可。另外,可以指定上下文,例如上面的 hobbies,内嵌的for的上下文 #data 就是hobbies,而外部的 #data 是整个arr。

  #index 当前下标。应该用 #getIndex() 去获得。

  #parent 当前上下文所在的视图。parent 属性可以一直往上查找视图,视图的data属性就是当前上下文。例如如果我们要在内嵌的for获得外部的name属性,就可以通过 #parent.parent.data.name 获得。

四、扩展应用

  上面的基本用法已经可以满足大部分需求了。以下几个扩展都是为了分离视图和逻辑的,试想一下,如果我们的视图里还需要大量的逻辑判断或计算,全都写在一起,那会非常麻烦和难以维护。视图最好就是简单的标签,而逻辑都写在js里。jsRender是在视图上进行扩展的。

4.1 自定义标签 Tag

  我们可以把标签里的逻辑移到自定义标签里。

  语法:1.视图 {{"标签名称" 标签参数 附加参数}}
           2.逻辑 $.views.tags({"标签名称":function(参数){this.tagCtx.props.prefix附加参数}}) 

  例子:

    <script type="text/tmp" id="tmp10">
{{for}}
<li>
name:{{:name}}
hobbies: {{format hobbies prefix="@" /}}
</li>
{{/for}}
</script>
$.views.tags({
"format":function(hobbies){
if(!hobbies || hobbies.length <= 0){
return "无";
}
var result = "";
for(var i = 0,length = hobbies.length;i < length; i++){
result += "," + this.tagCtx.props.prefix + hobbies[i];
}
result = result.substring(1);
return result;
}
})
var html = $("#tmp10").render(arr);
$("#list").html(html);

4.2 转换器 converter

  转换器可以对输出结果进行处理,例如大小写转换等。

  语法:1. 视图 {{"转化器名称":参数}}
          2. js $.views.converters({"转换器名称":function(参数){...}})

    <script type="text/tmp" id="tmp11">
{{for}}
<li>
Upper Name: {{toUpper:#parent.data.name}}
</li>
{{/for}}
</script>
$.views.converters({
"toUpper":function(name){
if(name){
return name.toUpperCase();
}
}
})
var html = $("#tmp11").render(arr);
$("#list").html(html)

4.3 辅助函数 Helper

  扩展函数可以对结果进行处理,逻辑判断等等。

  语法 1. 视图 {{~辅助函数名称(参数)}}
          2. js $.views.helpers({"辅助函数名称":function(参数){}})

    <script type="text/tmp" id="tmp12">
{{for}}
<li>
name: {{:name}}
hobbies: {{:~concat(hobbies)}}
</li>
{{/for}}
</script>
$.views.helpers({
"concat":function(hobbies){
if(!hobbies || hobbies.length <= 0){
return "";
}
var result = "";
for(var i = 0,length = hobbies.length;i < length;i++){
result += "&&" + hobbies[i];
}
return result.substring(2);
}
})
var html = $("#tmp12").render(arr);
$("#list").html(html);

五、总结

  jsRender还是比较新的,使用起来也比较方便。不过我们看到我们的数据和页面之间是一个单向的过程,而且是一次性的单向;也就是当我们的数据改变时,视图不能自动更新,而界面的数据改变时,实际数据也不能自动改变。设想一下,如果数据和视图是双向的,其中一个改变,都可以自动更新另外一个,那不就最好了,我们只需要操作数据,不需要操作dom了。这就是mvvm的机制,前端的mvvm框架有很多:knockout、angular等。下一篇将开始介绍knockout。

knockoutJS学习笔记02:jsRender模板引擎的更多相关文章

  1. jsRender模板引擎

    jsRender模板引擎 上一篇最后提到了模板,并尝试自己编写一个最简单版本:有些朋友可能用过 jqtmpl,这是一个基于jquery的模板引擎,不过它已经不再更新了,而且据说渲染速度比较慢.这里介绍 ...

  2. 软件测试之loadrunner学习笔记-02集合点

    loadrunner学习笔记-02集合点 集合点函数可以帮助我们生成有效可控的并发操作.虽然在Controller中多用户负载的Vuser是一起开始运行脚本的,但是由于计算机的串行处理机制,脚本的运行 ...

  3. 机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN)

    机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN) 关键字:邻近算法(kNN: k Nearest Neighbors).python.源 ...

  4. OpenCV 学习笔记 02 使用opencv处理图像

    1 不同色彩空间的转换 opencv 中有数百种关于不同色彩空间的转换方法,但常用的有三种色彩空间:灰度.BRG.HSV(Hue-Saturation-Value) 灰度 - 灰度色彩空间是通过去除彩 ...

  5. 微信小程序开发:学习笔记[2]——WXML模板

    微信小程序开发:学习笔记[2]——WXML模板 快速开始 介绍 WXML 全称是 WeiXin Markup Language,是小程序框架设计的一套标签语言,结合小程序的基础组件.事件系统,可以构建 ...

  6. SaToken学习笔记-02

    SaToken学习笔记-02 如果排版有问题,请点击:传送门 常用的登录有关的方法 - StpUtil.logout() 作用为:当前会话注销登录 调用此方法,其实做了哪些操作呢,我们来一起看一下源码 ...

  7. Redis:学习笔记-02

    Redis:学习笔记-02 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 4. 事物 Redis 事务本 ...

  8. knockoutJS学习笔记01:从拼接字符串到编写模板引擎

    开篇 关于knockout的文章,园里已经有很多大神写过了,而且都写得很好.其实knockout学习起来还是很容易的,看看官网的demo和园里的文章,练习练习就可以上手了(仅限使用,不包含研究源码). ...

  9. knockoutJS学习笔记06:ko数组与模板绑定

    前面已经介绍了基本的绑定和模板相关知识,接下来就看ko里的数组和模板绑定,数组和模板绑定应该是实际项目中用得比较多的,ko提供了很好的支持. 一.observaleArray 前面的监控属性都是单个对 ...

随机推荐

  1. 简单实用的二级树形菜单hovertree

    原创 hovertree是一个仿京东的树形菜单jquery插件,暂时有银色和绿色两种. 官方网址:http://keleyi.com/jq/hovertree/欢迎下载使用 查看绿色效果:http:/ ...

  2. iOS开发工程师面试题(二)

    1.手写冒泡跟插入排序 冒泡排序来源于生活常识,相当于把数组竖起来,轻的向上,重的向下.void bubbleSort(int[] unsorted) { ; i < unsorted.Leng ...

  3. jxl导入导出实例

    1 package com.tgb.test; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.Ar ...

  4. 使用memadmin可视化监视我们的memcache

    相信还是有很多项目使用memcache,可能有些人说有点out了,但是呢??? 项目上的东西不是你想换就能换的...谁都想多一事不如少 一事,大面积更换之后所面临的未知风险可能让你无法承受,但是呢, ...

  5. JQuery.Ajax之错误调试帮助信息

    下面是Jquery中AJAX参数详细列表: 参数名 类型 描述 url String (默认: 当前页地址) 发送请求的地址. type String (默认: "GET") 请求 ...

  6. webapi 控制器接收POST参数时必须以对象的方式接收

    webapi    控制器接收POST参数时必须以对象的方式接收

  7. vs与qt配置

    1.error: these Qt version are inaccessible;Qt5.4.0 in D:\qt5.4.0\5.4\msvc2013Make sure that you have ...

  8. 自动创建WIN32下多级子目录的C++封装类

            这是 WIN32 自动创建多级子目录的 C++ 封装类,用法简单.         封装没有采用类的静态函数方式,而是在构造函数里面直接完成工作.没什么具体的原因,只是当时做成这样了, ...

  9. [iOS]技巧集锦:UICollectionView内容下沉64像素原因和解决方案

    现象 UICollectionView的内容在按Home键再回到APP时,会下沉64像素. 原因 页面有NavigationBar,正好是64像素,Controller勾选了Adjust Scroll ...

  10. spark streaming kafka example

    // scalastyle:off println package org.apache.spark.examples.streaming import kafka.serializer.String ...