• Velocity模板开发常见问题分享


    在twitter上看到 @Fenng 提到“国内分享velocity的不多”,忽然想起自己在支付宝用velocity开发了两年,和服务端开发同学也常为这个模板层的归属问题纠结不休。这也是我在淘宝上买这件velocity主题T恤的原因,上次去红京鱼吃饭,工友们对它表示了很大的兴趣^_^

    直入话题,把自己这两年的velocity开发经验的精华部分分享出来吧,相信足以应对前端模板开发的日常工作。这里我准备了一个VM版的,有运行环境的同学可以放上去跑起来看看。

    问:遇到vm模板开发的问题一般怎么解决?

    首先官方手册PDF还是要收藏一份,英文的看不了,就去google上搜份中文手册看。手册上没有提及的只有去google.com(google.cn基本搜不到)上搜索了,用上一些英文关键字一般可以找到,实在找不到只有问周围的专业人士了。

    问:如何通过URL传递整型变量到VM里?

    这个问题是我在做项目的时候遇到的一个实际问题,传一个参数进来,然后运算下。当时在国外一篇很老的归档帖子中看到了解决方案。set一个新整型,然后调用它的parseInt方法把string转成int,再进行计算,代码如下:
    #set($n = $!request.getParameter('n'))
    #set($intNum = 0)
    #set($m = $intNum.parseInt($n) + 1)

    问:#parse和$tile.setTemplate()(或$control.setTemplate())区别是啥?

    • #parse是先插入后解析,$tile是先解析后插入。
    • #parse和被#parse的页面变量相互共享,$tile变量需要传入。
    • #parse是代码块无须controller,$tile是通用组件需要controller。
    • #parse需要配置系统的默认path,推荐能用#parse就不要用$tile

    问:VM模板里能取到哪些业务的值?

    VM是模板解析层,一般可以通过$request取到很多业务数据。比如从当前request对象中取cookie:

    #foreach($cookie in $request.getCookies())
    $cookie.name : $cookie.value
    #end

    问:${catge}、$!catge、$catge这些写法有啥区别?

    这三种写法语义上是等价的。${catge}比$catge的好处是,可以用{}符号隔开变量和其他文字。$catge和$!catge区别在于当页面中不存在$catge时,$!catge将会不会再页面中显示。

    问:VM里的循环、取对象什么的咋搞?

    循环啥的,学会怎么用#foreach语句就好了,想知道更多去Google下velocity的参考文档。循环能做的事情很多,比如上面的遍历出request里的cookie。

    这里举个绑定一系列元素的JS表单校验的例子:

    "attach3": {
    desc: "附件3",
    depends : true,
    required: true
    },
    "attach4": {
    desc: "附件4",
    depends : true,
    required: true
    },
    "attach5": {
    desc: "附件5",
    depends : true,
    required: true
    },

    千万别copy大段相通的VM代码,用这句:

    #foreach ( $count in [3..5] )
    "attach${count}": {
    desc: "附件${count}",
    depends : true,
    required: true
    },
    #end

    如果attch5是最后一个绑定元素呢?那最后一个逗号“,”就不要打出来,这里就引申出一个问题:怎样判断是否为循环的最后一次?

    这里要用到一个叫$velocityCount的变量,任何循环语句中都默认有这么一个标识当前循环次数的变量,而数组的长度都可以通过size()方法获取到。

    源码:

    #set($array = [3,4,5])
    #foreach ( $count in $array )
    "attach${count}": {
    
    desc: "附件${count}",
    depends : true,
    required: true
    }#if($velocityCount !=$array.size()),
    #end
    #end

    问:听说VM里有宏定义,这个啥东东?

    宏定义#macro就是把一些操作封装成类似function的方式来统一处理同类问题,具体你自己去google吧。有兴趣的话建议搜索系统当中叫macros-default.vm(或macros.vm)的文件,一般的宏定义都会写在这个文件里。
    需要说明的是,宏定义一般是放在某car的根目录上,在页面上也可以直接定义。宏定义修改之后需要deploy当前系统,否则方法会被缓存,看不到改动后的效果。

    问:VM里怎样生成随机数

    VM强大之处其实在于它的工具类,例如一般的VM都默认有$stringUtil这个字符串比较的类。
    有时我们需要给URL后加个随机数清清缓存。在webx系统你可以用$randomUtils.nextDouble(),在sofa MVC试试$math.getRandom(),如果不起作用,检查下是否配置了相应的工具类。

    问:如何通过VM来获取当前页面URL?

    貌似前面已经提到VM可以随意调用$request对象里的方法,获取到需要的值。

    //webx下获取当前页:
    $rundata.getRequest().getServerName()$rundata.getRequest().getServletPath()
    //sofa MVC下获取当前页:
    #set($pageAbsUrl = "$!request.getServerName()"+"$!request.getContextPath()"+"$!request.getServletPath()")
    //获取引用页:
    $rundata.getRequest().getHeader("referer")

    问:VM该前端开发来做还是服务端开发来做?有啥意义?

    @catge认为服务端提供数据、接口,前端进行VM、CSS、JS开发。因为VM是DOM结构层,样式和脚本都要基于结构开发。
    比如有一个需求是为某些浏览器的用户增加一个全站的XBOX弹窗,提醒用户升级到股沟浏览器。你有两种选择方案,一种是用JS判断UA信息为该浏览器,然后将已经生成好的XBOX的DOM弹出来。第二种方案是在VM里取request里的http头信息里的UA信息,判断符合条件则生成这段DOM。
    咋一看,这两种方法差不多,而且通过VM来实现更复杂,因为VM里取浏览器类型和版本号十分困难,$stringUtil折腾来折腾去都没有JS来得快。
    但是如果需求方说的浏览器是指IE6.0以下版本的浏览器呢?为了几千个用户给几亿用户的前端代码里加上这段JS判断?那只能说你很2。
    @catge认为VM层的模板优化至关重要,VM不应该只包含业务逻辑,同时应该使用大量的展现逻辑,针对不同用户、不同来源、不同浏览器展现最优体验。

    欢迎关注我的微信公众号「猫哥学前班」

  • 相关阅读:
    find文件及目录后的一些操作
    Firefox关闭GET请求到detectportal.firefox.com网站的方法
    Shell脚本自定义批量生成ip
    Nginx关闭危险的HTTP请求
    个人总结
    软件工程第二次作业--结对编程
    软件工程第一次作业
    C#中使用存储过程返回值的问题(转)
    使用SqlDataAdapter时,需要注意的几点(转)
    Sql连接查询(转)
  • 原文地址:https://www.cnblogs.com/kaiye/p/3039048.html
Copyright © 2020-2023  润新知