千里冰封
JAVA 浓香四溢
posts - 151,comments - 2801,trackbacks - 0
在使用JSF的时候,它的事件驱动模式是一个很好的开发方法,但是由于JSF毕竟现在的版本才1.2,所以对于有些细节上面处理就不一定如人意了,一般来说,当JSF的页面验证有错或者有其它的错误的时候,我们以前输入的值会在渲染页面的时候,恢复回来,也就是说,一个域我们绑定在后台的属性是一个int值,但是我们前台输入了“abcd”,这个时候,后台在验证阶段就过不去了。然后直接渲染页面,JSF 会把我们输入错误的abcd渲染出来。而不是把我们以前绑定在后台的那个属性的值,取出来,这样也正是我们想要的结果,但是当我们的页面包括了dataTable的时候,并且DataTable里面的值是可以编辑的时候,当页面上有错误的时候,别的域都会显示刚才我们输入的值,唯有DataTable里面的输入域的值没有还原为我们刚才输入的值,而是绑定在后台的值,这显然不是我们想要看到的。但是当DataTable有错误的输入的时候,DataTable才会把它的值恢复回来。说了这么说,感觉有点语无伦次了,还是拿代码说话吧。

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>

<%--
    This file 
is an entry point for JavaServer Faces application.
--%>
<f:view>
    
<html>
        
<head>
            
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            
<title>JSP Page</title>
            
<style>
                .header
{
                    background-color
:white;
                
}
                #mainForm\:data input
{
                    border
:0;
                    color
:red;
                
}
            
</style>
        
</head>
        
<body>
            
<h:form id="mainForm">
                
<h:messages style="color:red" />
                名字:
<h:inputText id="listName"  value="#{Test1.listName}" >
                    
<f:validateLength maximum="5"/>
                
</h:inputText>
                
<h:commandButton value="Submit" action="#{Test1.save}"/>
                测试用的:
<h:inputText id="testName" value="#{Test1.testName}"/>
                
<h:dataTable headerClass="header" rowClasses="header" bgcolor="blue" cellspacing="1" cellpadding="0" 

border
="0" value="#{Test1.listDataModel}" id="data" var="p">
                    
<h:column>
                        
<f:facet name="header">
                            
<h:outputText value="Name"/>
                        
</f:facet>
                        
<h:outputText style="background-color:white;width:100%" id="name" value="#{p.name}"/>
                    
</h:column>
                    
<h:column>
                        
<f:facet name="header">
                            
<h:outputText value="Sex"/>
                        
</f:facet>
                        
<h:inputText  id="sex" value="#{p.sex}"/>
                    
</h:column>
                    
<h:column>
                        
<f:facet name="header">
                            
<h:outputText value="Age"/>
                        
</f:facet>
                        
<h:inputText  id="age" value="#{p.age}"/>
                    
</h:column>
                    
<h:column>
                        
<f:facet name="header">
                            
<h:outputText value="Email"/>
                        
</f:facet>
                        
<h:inputText id="email" value="#{p.email}"/>
                    
</h:column>
                
</h:dataTable>
            
</h:form>
        
</body>
    
</html>
</f:view>

通过以上的代码我们就可以发现问题了。在查看了JSF的源代码才发现,DataTable有一个特殊的处理机制,那就是只有它自己包含在另外一个DataTable的时候,或者它自己内部的值有错的时候,才会渲染submittedValue,否则,它只会渲染绑定在后台的值。知道这一点以后,就非常好解决了,那就是在我们的DataTable有外层再包括一个DataTable,当然,它外层的DataTable最好不要有具体的值,所有我们就包含一个空的DataTable来实现它了,这样解决有点不太好看,但是也是没有办法的办法了。呵呵,希望JSF2.0中对此会有一些改进。
改后的代码如下:

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>

<%--
    This file 
is an entry point for JavaServer Faces application.
--%>
<f:view>
    
<html>
        
<head>
            
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            
<title>JSP Page</title>
            
<style>
                .header
{
                    background-color
:white;
                
}
                #mainForm\:data input
{
                    border
:0;
                    color
:red;
                
}
            
</style>
        
</head>
        
<body>
            
<h:form id="mainForm">
                
<h:messages style="color:red" />
                名字:
<h:inputText id="listName"  value="#{Test1.listName}" >
                    
<f:validateLength maximum="5"/>
                
</h:inputText>
                
<h:commandButton value="Submit" action="#{Test1.save}"/>
                测试用的:
<h:inputText id="testName" value="#{Test1.testName}"/>
                
<h:dataTable value="1"><!--只是在这里加了一个空的DataTable-->
                    
<h:column>
                        
<h:dataTable headerClass="header" rowClasses="header" bgcolor="blue" cellspacing="1" 

cellpadding
="0" border="0" value="#{Test1.listDataModel}" id="data" var="p">
                            
<h:column>
                                
<f:facet name="header">
                                    
<h:outputText value="Name"/>
                                
</f:facet>
                                
<h:outputText style="background-color:white;width:100%" id="name" value="#

{p.name}"
/>
                            
</h:column>
                            
<h:column>
                                
<f:facet name="header">
                                    
<h:outputText value="Sex"/>
                                
</f:facet>
                                
<h:inputText  id="sex" value="#{p.sex}"/>
                            
</h:column>
                            
<h:column>
                                
<f:facet name="header">
                                    
<h:outputText value="Age"/>
                                
</f:facet>
                                
<h:inputText  id="age" value="#{p.age}"/>
                            
</h:column>
                            
<h:column>
                                
<f:facet name="header">
                                    
<h:outputText value="Email"/>
                                
</f:facet>
                                
<h:inputText id="email" value="#{p.email}"/>
                            
</h:column>
                        
</h:dataTable>
                    
</h:column>
                
</h:dataTable>
            
</h:form>
        
</body>
    
</html>
</f:view>


如果大家还有什么更好的方法,也希望能分享一下,这里只帖出来了JSP的代码,JAVA代码就没帖了,因为都是一些getter,setter方法。








尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.
posted on 2009-02-28 11:17 千里冰封 阅读(5559) 评论(2)  编辑  收藏 所属分类: JAVAEE

FeedBack:
# re: JSF页面出错的时候,DataTable不能恢复原有值的解决办法
2009-02-28 11:41 | 打酱油的
不看好JSF,虽然是事件驱动,但在速度、语法、效率上都没有优势,唯一优点就是易重用,但远不如ASP.NET简便,甚至连Tapestry也有所不及。因为是sun提供,倒是很适合企业开发的标准化(招工和辞人都方便),但不会有大的发展。  回复  更多评论
  
# re: JSF页面出错的时候,DataTable不能恢复原有值的解决办法
2009-02-28 11:50 | 千里冰封
@打酱油的
呵呵,仁者见仁,智者见智吧,这种东西不会因为某些人的不看好就一定不好,也不会因为某些人的看好,就一定有好的发展。
这些都只是工具,能从这些工具中,总结出自己的想法,那才是最重要的。
每一个框架都有它设计的优秀的地方。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: