下一代Jquery模板-----JsRender(2)JsRender扩展

  下一代Jquery模板-----JsRender中提到,JsRender由Jsrender标签+Html标签组成。说道Html,就很容易想起xml,xml和html一个显著的不同点就在于:xml是可扩展标记语言,也就是说,xml可以根据你的需要自己定义标签(当让要符合良好的xml格式),这就很方便了(当然不是说html不好,试想如果大家都用自己定义的标签来展示网页结构,那不惨了)。JsRender可以不勒?可以。除了下一代Jquery模板-----JsRender说的{{:}}、{{>}}、{{for /}}、{{if  /}}等之外,还可以自己定制Jsrender标签、转换器、辅助函数等。这些都使JsRender具有良好的扩展性。

  问题纠正

  在下一代Jquery模板-----JsRender中,说道#parent关键字的时候,我说是#perent返回的是一个JsRender对象,这样说是不准确的。其实#parent返回的是当前视图#view,通过#view.data可以访问当前视图的上下文数据---#data。

<li><b>{{:#view.data.name}}</b>({{:#data.releaseYear}})</li>//{{:#view.data.XXX}}就相当于{{:#data.XXX}}

   自定义JsRender标签

  在Jsrender中,提供了很多进行数据绑定、逻辑处理等的标签,如{{for /}}、{{if /}}等等,但是当面临复杂的逻辑处理时候(当然我们不可能把复杂的逻辑处理放在客户端,那么系统的扩展性就不是很理想了,所以个人感觉掌握Jsrender提供的标签已经够用了),我们肯定会被{{for /}}、{{if /}}弄的焦头烂额,因为这样模板本省的可见性已经降低了,或许后期维护的时候,还需要花大量的时间去阅读模板,事倍功半了。所以,Jsrender提供了自定义标签,降低逻辑和表现之间的耦合。

//使用自定义Jsrender标签:{{tagName Entity  params=values}}
<li>{{:Name}}({{format Languages saySomething = "The analysis of languages:" /}})</li>
///定义Jsrender自定义标签:$.views.tags({tagName:function(Entity){XXX}})
$.views.tags({
                format: function (Languages) {
                    var ret = "";
                    if (this.props.saySomething) {
                        ret += this.props.saySomething;
                    }
                    for (var i = 0; i < Languages.length; i++) {
                        ret += Languages[i];
                        if (i == Languages.length - 2) {
                            ret += " and ";
                        }
                        else if (i < Languages.length - 2) {
                            ret += " , ";
                        }
                    }
                    return ret;
                }
            });

  从上面的东东可以看到,JsRender自定义标签需要注意两点:

  1、Jsrender自定义标签的方法:$.views.tags({tagName:function(Entity){XXX}})。自定义标签的调用:{{tagName Entity params=values}}。可以看到实体(姑且这么说哈)既是需要渲染的属性,和{{:Name}}中的Name一样。

  2、实体后还可以跟参数,格式如下:ParamName = value,在$.views.tags的定义时,通过this.props.XXX获取。

  试想一下,当面对比较复杂的逻辑时候,如果用自定义标签来解决,那模板的可见性是不是更高了呢?这就可以看到模板的好处。而且面临相对复杂的逻辑,当这个自定义标签在整个应用程序中使用的时候,Jsrender的重用性也进一步体现了。

  JsRender转换器

  表面上看,JsRender转换器可以看做是自定义JsRender的一个补充,因为除了除了语法不通之外,唯一不通之处便是:JsRender自定义标签可以指定参数,但是转换器不能。这是由他们的本质决定的。转换器主要负责数据的转换,例如将字符串全部转换为大些。。(貌似说的不清不楚的,看下面例子就懂了)等等,但是自定义标签和{{for/}}一样,是标签,所以可以指定参数。(不清不楚啊。。。看看下面例子。。。慢慢体会啊。。。。)。一般情况,我优先选择转换器,因为更轻量级些(仅限于感觉。。。。)

//转换器调用:{{converterName:XXX}}
<li>{{format:#data}}</li>

 //转换器定义:$.views.converters({converterName:function{XXX}})
var names = ["AAA", 1, true];
         $.views.converters({
             format: function (name) {
                 return name + " is a " + typeof (name);
             }
         });
         var nameHtml = $("#nameTemplate").render(names);
         $("#nameList").html(nameHtml);

  JsRender辅助函数

  除了JsRender自定义标签和转换器,JsRedner还提供了辅助函数。辅助函数的定义、调用和自定义标签以及转换器都差不多,当然我也不知道为什么会有个这个东东存在。貌似这三个东东分别标志着:标签、数据转换、函数三个基本上的扩展。废话少说,先看看辅助函数的定义和调用:

//辅助函数应用:{{~FuncName(params)}}
<li>{{:name}}{{if ~nextToLast()}} and {{else ~notLast()}}, {{/if}}</li>
//定义:$.views.helpers({funcName:funciton(params){XXX}})
$.views.helpers({
        nextToLast: function() {
            var view = this;
            return view.index === view.data.length - 2;
        },

        notLast: function() {
            var view = this;
            return view.index !== view.data.length - 1;
        }
    });

  这里需要注意的三点:1、我们可以同时定义多个自定义标签、转换器和辅助函数(如上)。2、辅助函数、转换器、自定义标签中的this,表示的是当前视图。所以需要获取数据的时候需要this.data.XXX(parent、index等等)。3、注意这里不能直接 return this。因为这个时候返回的是当前视图对象,在模板中无法直接解析,最好的处理方案是利用this.renderContent(view)返回数据上下文对象。

  ok,终于是写完了。这篇博客主要想证明,JsRedner不仅渲染性能上有很大的提升,而且JsRender具备良好的扩展性。我们可以通过自定义JsRender标签、转换器、辅助函数轻松的扩展复杂的逻辑和标签。而且这里的应用都相对简单,JsRender可以处理各种复杂的逻辑,详细的还是参考官网上:https://github.com/BorisMoore/jsrender 。不足之处,继续改进。

posted @ 2012-06-05 23:31  堂堂88  阅读(5283)  评论(7编辑  收藏  举报