JsRender 常用API
1. $.templates()
$.templates()方法是用来注册或编译模板的,使用的情况有以下几种。
- 把html字符串编译编译成模板
- 获取使用script标签声明的模板,并返回一个模板对象
- 把html字符串或者在script标签中声明的模板注册成命名模板
- 获取之前就存在的命名模板
- 在nodejs中,根据文件路径获取一个模板对象
我们正常使用的方式就是使用$.templates()方法把html字符串编译成模板,返回一个模板对象,然后调用该对象的render方法并传入数据,就可以得到一份完整的html字符串代码。比如:
或者我们也可以给模板定义一个名称
//定义一个命名模板$.templates('myPersonalInfoTpl', '{ {:name}}
{
{:age}}
当然,我们也可以把html字符串单独写在script标签中,然后根据id来获取
更想当然,还可以在一个templates()方法里面注册多个命名模板
还可以指定一些只供这个模板使用的一些方法
2、渲染模板的render()方法
当我们使用$.templates()方法注册一个模板对象时,最后还是需要把模板对象跟数据结合得到最终的html字符串的,render()的使用方式有以下三种。//定义一个匿名模板 var myPersonalTpl = $.templates("#tml"); //模板与数据结合 var finalTpl = myPersonalTpl(info);
当模板对象myPersonalTpl是以命名模板的方式注册时,需要使用$.render.myPersonalTpl(data)或者$.render['myPersonalTpl'](data)的方式来渲染模板
//定义一个命名模板$.templates("myPersonalInfoTpl","#tml");//模板与数据结合var finalTpl = $.render.myPersonalInfoTpl(info);
当使用jQuery、并且模板是在script标签中声明时,还可以直接使用$("#personTemplate").render(data),并不需要调用$.templates()方法来注册模板。
var myHelpers = { upper: function(val){ return val.toUpperCase(); } } //使用jQuery选择器获取script标签声明的jsrender模板,并传入数据跟一些方法渲染模板。 var html = $("#tml").render(data, myHelpers); $('select').html(html);
//example{ {:~myHelperValue}}{ {:~myHelperFunction(name, title)}}{ {for ~myHelperObject.mySortFunction(people, "increasing")}} ... { {/for}}
辅助函数helper注册方式有以下三种:
- 使用$.views.helpers()注册全局的helper方法。当我们需要一些比较通用的方法时,可以提取出来写到公用的js文件中去,以后就不用重新写一遍了。
// 定义全局的helper方法 $.views.helpers({ concat: function(first , last){ return first + ' ' + last; }, util: { prefix: 'age is ', addPrefix: function(age){ return this.prefix + age; } } });
- 写局部的辅助方法当我们的某一个页面有多处使用一个辅助方法,但是又不够通用,不必写到common文件去时,我们可以写只供这个页面使用的辅助方法。
// 定义局部的helper方法 var myHelper = { concat: function(first , last){ return first + ' ' + last; }, util: { prefix: 'age is ', addPrefix: function(age){ return this.prefix + age; } } } //并在渲染模板的时候把myHelper当做参数传进去 var html = $('#tml').render(data, myHelper);
- 只给特定的模板写辅助函数,其实也就是在定义模板的时候把helper传进去
//注册一个命名模板,并指定helper方法 $.templates({ myPersonInfo: { markup: '#tml', helpers: { concat: function(first , last){ return first + ' ' + last; }, util: { prefix: 'age is ', addPrefix: function(age){ return this.prefix + age; } } } } }); //渲染模板,命名模板只能使用$.render调用 var html = $.render.myPersonInfo(data); $('#box').html(html);
4、使用$.views.converters()注册转换器
在jsrender中,转换器主要是方便对数据或表达式的的结果进行处理或者格式化,jsrender本身自带了三个转换器,比如:{ {html:'bolin'}} //- 对html标签进行编码,原样输出 :bolin{ {>'bolin'}} //同上,html的别名{ {url:"<_>_\"_'"}} // 对特殊字符进行编码 基本是 <,>,",'... :%3C_%3E_%22_'{ {attr:value}} //对标签的属性值进行编码,也是字符的转换
当然,仅仅是这三个转换时不够用的,jsrender提供了自定义转换器的方法。$.views.converters()。比如我想要定义一个时间格式化的转换器跟大小写转换的转换器。
你会发现,其实转换器跟辅助函数差不多,只是使用的方法不一样而已。虽然实现都差不多,但还是有点区别的,转换器也分全局定义跟局部定义,局部定义的转换只要把模板当做参数传进去就好了,所定义的转换器只能在此模板中生效。
//注册局部转换器,指定myPersonInfo模板可用 $.views.converters({ dateFormat: function (val) { var time = new Date(); return (time.getMonth() + 1) + '月' + time.getDate() + '日'; }, upper: function (val) { console.log(val); return val.toUpperCase(); } }, $.templates('#tml'));
除了使用在{
{convert:}}标签中之外,还可以在{ {if}},{ {for}}标签中使用,语法如下://if语句{ { if convert='inList' }}...{ {/if}}//for语句{ { for people convert='even'}}...{ {/for}}
在其他标签中使用时,只是需要把转化器赋值给convert,当然也可以把辅助方法赋值给convert,比如
{ {:name convert=~hlp.bold}}
jsrender 提供了一些内置的标签,但往往是不够用的,所以提供了$.views.tags()方法来定义一些比较灵活的标签。自定义标签比较灵活,能控制、访问的元素也比较多,比如写在该标签里面的args、props、甚至整个view model对象里面的全部数据。使用$.views.tags注册自定义标签的语法有以下四种
- $.views.tags('myTag', tagOptions); 当自定义的标签需要要模板与方法时,一般会使用这种方式来注册自定义标签,我们可以在render方法里面处理参数或者属性,然后渲染模板,this.tagCxt对象下,有当前view model的数据供访问
当然,如果我们不需要模板,那么就只定义一个方法就好了。
$.views.tags('myPersonInfo', function(){ if (this.tagCtx.props.addPrefix) { return 'Hello, ' + this.tagCtx.args[0] + '
' + this.tagCtx.args[1] + '
'; } });
当然,也可能你的自定义标签只需要模板,并不需要方法来处理,那么也是没问题的,当然模板里面也是可以访问各种参数、属性的,只是需要使用~tag.tagCtx对象访问。
$.views.tags('myPersonInfo', { template: '{ {:~tag.tagCtx.args[0]}}
{
{:~tag.tagCtx.props.age}}' }); //也可以这样 //也可以使用tag.tagCtx.content获取到自定义标签中的内容 $.views.tags('myPersonInfo', { template: '{ {if ~tag.tagCtx.props.addPrefix == true}}\Hello, { {:~tag.tagCtx.args[0]}}
\{
{:~tag.tagCtx.props.age}}\ { {else tmpl=~tag.tagCtx.content}}\ { {:~tag.tagCtx.content}}\ { {/if}}' }); //或者这样 $.views.tags("range", { template: "{ {for ~tag.tagCtx.args[0]}}" + "{ {if #index >= ~tag.tagCtx.props.start && #index <= ~tag.tagCtx.props.end}}" + "{ {include tmpl=~tag.tagCtx.content/}}" + "{ {/if}}" + "{ {/for}}" });
当然也可以为某个模板注册私有的自定义标签
$.views.tags({ myTag1: ..., myTag2: ... }, parentTemplate);
6、使用$.views.settings.debugMode()开启调试模式
当我们使用jsrender写代码时,难免会报一些错,然后直接在控制台抛出错误异常。但是我们想对错误信息做一些处理,比如直接把异常输出到页面,或者自定义错误信息为字符窜,或者抛出错误的时候,先调用函数处理再抛出错误。jsrender提供了$.views.settings.debugMode()传入不同的参数来改变全局抛出异常的情况。
- false 内容不会被渲染并且在控制台抛出异常 (默认)
- true 抛出的异常会渲染在页面中,在控制台中没有异常抛出
- "string" 字符串会替代错误信息渲染在页面中,在控制台没有异常抛出
- function 在异常抛出之前,会先经过传入的方法处理,如果此方法没有return,那么就会把错误信息渲染到页面中,如果有return,那么页面中就会渲染return 的信息
$.views.settings.debugMode(function(err){ var errMsg = ''; if(err){ errMsg = 'here has error the err is ' + err; } return errMsg; });
当然,除了为全局处理错误信息之外,也可以使用onError属性为某一个标签定义错误信息,如果你已经在全局设置了处理错误信息的方法,并且传入的参数有返回值(上面提到的3跟4),onError属性是不会起作用的
{ {:address.street onError="Address unavailable"}} { { for phones() onError="No phones"}} { {:address.street onError=name + " has no address"}} { {:address.street onError=~errorMessages(1, name, 'address')}} { {myCustomTag ... onError=""}} $.views.settings.debugMode("this is global err"); //会覆盖上面的onError属性 or $.views.settings.debugMode(function(err){ var errMsg = ''; if(err){ errMsg = 'here has error the err is ' + err; } return errMsg; //如果return 就会渲染这个,如果不return 就会渲染onError属性的值 });
当我们使用render()方法渲染模板的时候,我们想查看某个对象或者某个属性的值,但是并不能在模板中打断点,jsrender提供以下方式在渲染模板的过程中输出对象或者属性的值
{ {dbg expression/}} tag{ {dbg: expression}} convert{ {:~dbg(expression)}} helper
以上的三种方式都会把值渲染在页面,并在控制台中输出值,但是呢,如果值是一个对象,那么就会输出字符串,比如
JsRender dbg breakpoint: [object Object]
我们需要看对象里面有什么属性,但是却给我们输出的是字符串,显然不方便调试,所以我们可以重写这个调试标签,让输入值原样输出
//重写dbg调试模式 $.views.helpers({ dbg: function(val){ try { console.log(val); return val; }catch (e) { console.log(e); } } }); $.views.converters({ dbg: function(val){ try { console.log(val); return val; }catch (e) { console.log(e); } } }); $.views.tags('dbg', function(val){ try { console.log(val); return val; }catch (e) { console.log(e); } });
这样重写之后,控制台输出变成这样,就比较方便调试了
Object {name: "bolin", age: 20}