浏览 9724 次
锁定老帖子 主题:primefaces,看上去很美
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-03-31
一个月前,看了组件库primefaces的demo,心里想,这下子咱么可以把前端妹子们抛弃了,单干也可以。demo的url见http://www.primefaces.org/showcase-labs/ui/home.jsf。 两周前,在公司接了一个小项目,就试验了一下primefaces和jsf,完了以后发现这玩意儿,其实跟妹子的性格很象——顺心的时候,绝对让你很爽,以前要写大量代码,现在一句话可以搞定。但是有各种小脾气,发作的时候,经常让人找不着北,跌进坑里爬不出来。下面列举一下我掉进去的各类坑,也给有兴趣用jsf和primefaces的同学提个醒。 坑一:输入检测错误后,按钮指定的action不运行。jsf在检测错误后,不会运行后续方法。你可以用process属性指定你要提交的panel或控件。如果不指定process,默认提交所有控件,这样会导致你用不到的控件输入值错。 坑二:commandLinK和commandButton被点击的时候,如果process的控件中,不包括@this(如果this不在提交的form中或者panel中),那么对应的action或者actionListener不会被执行。如果你只想提交某个input的值,那么你的控件的process属性应该这么写:process="inputId,@this" 坑三:如果commandLinK在datatable里面,那么update="table"是无效的,原因不知道。解决方法很简单,在table外面再套一个panel,每次更新那个panel。 坑四:jsf和spring结合后,datatable通过lazyload调用spring的bean,如果该bean的scope不是session,就会报错。原因不知,如果这个bean是配置在face——config文件中,又不会报错。可能是spring版本的问题。 坑五:jsf和spring节后后,通过元数据ManagedBean,无法被页面的el表达式引用,原因未知,可能是spring版本的问题。 坑六:错误复位。假设以下场景,有一个表格,显示某张数据库表的数据。表格的最后一列有一个“修改”按钮。每次点击“修改”,弹出一个窗口上面有各类控件显示对应行的数据。然后点击“保存”,提交到数据库中进行保存。点击另外一行的“修改”,会弹出窗口显示另外一行的数据。问题是,当我点击“保存”后,如果发生检测错误,再选择另外一行进行修改,弹窗控件中的数据不会被更新。这个坑我掉进去很久,查了不少资料才知道可以用primefaces-extendsions的resetEditableValues标签可以解决,在commandButton中加入<pe:resetEditableValues for=":form:updatePanel"/>就可以了。 坑七:scope设成session后会有脏数据的问题,可以通过指定属性的方法强行刷新。比如每次提交的时候,提交一个id为refresh的hidden控件,而在后台的java类中的setRefresh方法 中将脏数据刷新。 坑八:没有拦截器。struts2的拦截器功能强大,经常用它做事务管理、日志记录、异常处理。jsf中有类似的phaseListener,但是功能不够强大。幸亏spring有aop,可以弥补这个问题。jsf的phaseListener不能得到当前运行的managebean的实例,实际上也无法得到,因为jsf每次提交可能涉及多个managebean,不像struts2只会有一个action。 坑九:datatable中c:if无法使用,原因未知。 虽然使用primeface遇到了不少问题,也发了不少牢骚,但是我觉得jsf以后还是一个发展方向。各大java开源组织也推出了不少自己的jsf实现或者组件库,像apache有myface和对应的一套组件库、jboss有richfaces、金蝶有他的京剧脸谱。还有一个icefaces也蛮有名。但是我还是比较喜欢primefaces,控件多,效果漂亮,配置也简单,文档也很齐全。 用了primeface后,有些功能原来很复杂的,现在基本上一句话可以搞定。比如隔5秒刷新一个表格, <p:poll interval="5" process="@this" update=":form:tablePanel" />。用了jsf最大的好处是前后台交互变得很少,前台直接调用后台的函数,也可以直接取得后台数据。基本上我们不用写ajax获取后台数据什么的,javascript也写得很少,因为组件库各类效果都帮你实现了。更诱人的是,你可以根据jsf规范自定义组件,组件库没有帮你实现的,可以自己实现。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-04-20
primefaces 非常不错,已经用了好一段了。
|
|
返回顶楼 | |
发表时间:2012-04-23
既然选择了jsf,你就得用seam,而不是什么spring。
用jsf开发的时候,请忘掉struts2。 |
|
返回顶楼 | |
发表时间:2012-04-23
不支持ie6,被迫无视
|
|
返回顶楼 | |
发表时间:2012-04-26
这么巧.........俺也在用primefaces做毕设..........的确有很多坑....
|
|
返回顶楼 | |
发表时间:2012-09-28
我在做datatable的时候懒加载问题太多!
|
|
返回顶楼 | |
发表时间:2012-09-28
primefaces是套组件库,需要结合一个JSF引擎来用的。你这里列的问题有些是JSF引擎的问题。JSF有自带的依赖注入体系,如果没有明确表明可以整合spring,在注入上就可能与spring有冲突。结合EJB来用会更为自然。
|
|
返回顶楼 | |
发表时间:2012-09-28
最后修改:2012-09-28
坑一:JSF正常情况下会保证Form的事务性,提交数据中只要有一个转换或校验出错,就会跳过action,这适用于通常的处理场景。但往往某些Ajax行为需要跳过无关数据的校验,通常JSF引擎都会提供一些非标准的方式(不同引擎方式不同)来实现。比如说Richfaces里可以用ajaxSingle属性指定忽略所有其他输入组件,用process来指定仅处理局部组件,或者用<a4j:region>来指定一个局部提交范围。
坑二:process指明本次请求处理中会处理的组件树分支。action事件的入队动作是在组件的decode方法中实现的。如果组件不在要处理的组件树分支中,decode方法根本不会执行,所以这个action根本没有进入事件队列,自然也不会执行。不过这与具体的JSF引擎实现有关。 坑三:Ajax下的局部页面刷新是依靠javascript替换浏览器上的dom结点的内部html。一些没有顶层div结点的组件是不支持局部刷新的。比如说datatable的顶层结点往往是table,要局部刷新的话,不能只替换table的内部内容,而要替换掉整个table,这时必须要有一个外部div(也就是JSF里的panel组件)作为父结点。一般来说,UIInput和UIOutput的子类组件(Form fields)都支持直接刷新,其他一些复杂组件要局部刷新最保险的办法是套在一个panel里然后刷新panel。 坑四:一个可能的原因是,JSF引擎如果没有特别整合spring的话,与spring走的是完全不同的生命周期。通常是先跑完spring再跑JSF。那么lazyload的话,在spring的生命周期中不会创建这个bean,到了JSF的生命周期里,要创建时,JSF根本不认得spring的配置。所以无效。 坑五:同上,JSF与spring没有做特别整合的话,可能使用了不同的上下文环境或命名方式,导致bean不能互用。但当scope为session时,刚好都放在servlet的http session里,结果刚好能互用。 坑六:不清楚具体情况,估计是“修改”按钮与其他输入组件放在了同一个form里,校验错误导致更新值的动作没有执行。视具体情况,可以把“修改”按钮设为immediate=true或者process=@this试试 坑七:不清楚具体情况 坑八:JSF2的phaseListener好像也支持注入了(没试过),不过只要在JSF的生命周期内,可以随时用编程方式求值EL表达式获得managedbean的实例。如果Richfaces,用Component.getInstance(BeanClass.class)就行 坑九:JSF中如果使用facelet来写页面,c:if是由facelet引擎实现的,而facelet只负责构建组件树,它的所有行为都只发生在JSF生命周期的第一阶段,在这个阶段时后台ManagedBean的值还没有更新,如果不清楚这点的话,可能对c:if的效果会有错误的预期。 |
|
返回顶楼 | |
发表时间:2012-10-04
广告做得好 没有新飞冰箱好
|
|
返回顶楼 | |
发表时间:2012-12-19
primefaces 应用在项目当中牛。
|
|
返回顶楼 | |