[Ajax4JSF] 对于JSF的表格真的是无语了

风之狐 2008-05-16
这个是我用来显示用户列表的一个表格
<t:dataTable id="users" var="user" style="margin-top: 10px"
    value="#{userList.users}" rows="25" sortColumn="#{userList.sortColumn}"
    sortAscending="#{userList.ascending}" styleClass="scrollerTable table"
    headerClass="standardTable_Header" rowClasses="standardTable_Row1,standardTable_Row2"
    columnClasses="standardTable_Column,standardTable_Column,standardTable_Column,standardTable_Column,standardTable_ColumnCentered">
    <t:column width="25%">
        <f:facet name="header">
            <t:commandSortHeader columnName="username" arrow="true">
                <h:outputText value="#{text['user.username']}" />
            </t:commandSortHeader>
        </f:facet>
        <h:commandLink action="#{userForm.edit}" value="#{user.username}" >
            <f:param name="id" value="1"/>
        </h:commandLink>
    </t:column>
    <t:column width="34%">
        <f:facet name="header">
            <t:commandSortHeader columnName="fullName" arrow="true">
                <h:outputText value="#{text['activeUsers.fullName']}" />
            </t:commandSortHeader>
        </f:facet>
        <h:outputText value="#{user.fullName}" />
    </t:column>
    <t:column width="25%">
        <f:facet name="header">
            <t:commandSortHeader columnName="email" arrow="true">
                <h:outputText value="#{text['user.email']}" />
            </t:commandSortHeader>
        </f:facet>
        <h:outputLink value="mailto:#{user.email}">
            <h:outputText value="#{user.email}" />
        </h:outputLink>
    </t:column>
    <t:column width="16%">
        <f:facet name="header">
            <t:commandSortHeader columnName="enabled" arrow="true">
                <h:outputText value="#{text['user.enabled']}" />
            </t:commandSortHeader>
        </f:facet>
        <h:selectBooleanCheckbox value="#{user.enabled}" disabled="true"/>
    </t:column>
</t:dataTable>

其中里面的按钮我都已经给加了参数了
        <h:commandLink action="#{userForm.edit}" value="#{user.username}" >
            <f:param name="id" value="1"/>
        </h:commandLink>

但是在点击的时候后台竟然是先取得所有用户的列表,然后才开始后续操作。我不想在后台保存太多数据,所以bean的上下文就定的request,现在每次点击后台的列表为空,数据下面的编辑操作就直接不进行了,真是够晕的。
要是所有bean都必须换成session才能确保不出问题,那这jsf的实用性也太差了。
rockjava 2008-05-16
看你的代码用的是MyFaces吧,那你可以是用<t:saveState/>这表标签来保存你数据表格中的数据,他可以使你的保存的数据在reqeust和session之间,这样你就可以把你的bean定义为request了。
风之狐 2008-05-16
但是那样每次提交就得把整个table的数据都返回的服务器,效率还是很低,对于这个列表,在这个方法的时候我根本就不需要这个table。我之所以用带参数的函数就是不想每次获得当前行的时候都重新检索整个数据库,现在还是有这种现象,我也试过richface,效果一样,估计是jsf框架造成的。
terryzhou 2008-05-17
你的想法是不错.但也可能造成脏数据...
我的做法都是点了编辑后,先读后改...
风之狐 2008-05-18
我的方法也是先查询出列表,点击编辑,弹出一个编辑窗口,编辑完成后刷新列表,但现在不知道怎么回事,在点编辑按钮时候后台就会刷新数据库去重新检索列表数据,并不是是要jsf表格直接编辑数据的。
那个给的参数就是user表的id号,后台也可以取得,我测试的时候直接就写了个1。
kimmking 2008-05-18
你也可以仅仅把pageIndex,query condition,保存在session。

这个是设计的问题 与datatable或是datascroll本身无关
terryzhou 2008-05-18
同上,设计问题。。跟你bean的具体实现有关系。。
建议你把bean贴出来
风之狐 2008-05-18
不会吧,我这个bean什么的都是基本的功能,分页什么的都没有。
//这个是获取list的
public class UserList extends BasePage implements Serializable {
    private static final long serialVersionUID = 972359310602744018L;
    
    public UserList() {
        setSortColumn("username");
    }
    
    public List getUsers() {
    	HttpServletRequest req=this.getRequest();
    	Map m=req.getParameterMap();
    	System.out.println(m);
         //下面这一段是我测试用的,把从数据库中取数注释了
    	List list=new ArrayList();
    	for(int i=0;i<10;i++)
    	{
    		Users u=new Users();
    		u.setId(new Long(i));
    		u.setUsername("OK:");
    		u.setFirstName("ok:");
    		u.setLastName(new Integer(i).toString());
    		u.setEmail("email");
    		u.setEnabled(true);
    		list.add(u);
    	}
        return list;//sort(userManager.getUsers(null));
    }
}
//这个编辑的
public class UserForm extends BasePage implements Serializable {
private String id;//这个可以从参数里面自动获得id的值。
   public String edit() {
        // if a user's id is passed in
        if (id != null) {
            // lookup the user using that id
            user = userManager.getUser(id);
        } else {
            user = userManager.getUserByUsername(request.getRemoteUser());
        } 

        if (user.getUsername() != null) {
            user.setConfirmPassword(user.getPassword());
            if (isRememberMe()) {
                // if user logged in with remember me, display a warning that they can't change passwords
                log.debug("checking for remember me login...");
                log.trace("User '" + user.getUsername() + "' logged in with cookie");
                addMessage("userProfile.cookieLogin");
            }
        }

        return "editProfile";
    }

}
这个例子其实就是appfuse的jsf例子。,然后我在获得list的那个bean里面加了断点发现每次点击编辑按钮的时候,还会重新检索list。
terryzhou 2008-05-19
1.你点了EDIT按钮以后是不是还要刷新dataTable所在的页面?

2.public List getUsers() {  
        HttpServletRequest req=this.getRequest();  
        Map m=req.getParameterMap();  
        System.out.println(m);  
         //下面这一段是我测试用的,把从数据库中取数注释了  
        List list=new ArrayList();  
        for(int i=0;i<10;i++)  
        {  
            Users u=new Users();  
            u.setId(new Long(i));  
            u.setUsername("OK:");  
            u.setFirstName("ok:");  
            u.setLastName(new Integer(i).toString());  
            u.setEmail("email");  
            u.setEnabled(true);  
            list.add(u);  
        }  
        return list;//sort(userManager.getUsers(null));  
    }  
这种代码比较忌讳....

2-1.建议里至少判断下list是否等于NULL,不等于NULL的话就别取记录了.
2-2.把list放到savestate里.
风之狐 2008-05-20
to:terryzhou
1.这个例子很简单,贴出来的页面代码是显示所有User的,点击的时候往后台传一个User的id参数,后台取得User数据后转发到新页面去编辑User信息,那个list页面应该是没有用了。
2.1这个代码就是测试用的,我试试看能不能获得id参数,还有就是不想去查数据库了,就自己构造了模拟的数据,用的时候肯定是判断list是否为空才查数据库的。有分页的时候,方法会调用两次 。不过判断为空的方法有个问题,就是列表中直接删除数据的时候(就是在列表中每行加个删除按钮),获得整个列表的方法会在删除方法之前进行,然后删除操作完成后数据就不再取得,页面中还会显示该记录实际上它已经删除了。我现在用的是加了一个更新变量,每次删除或者保存后就吧flag=true,取数据根据flag和list是否为空。但是这样也有问题,如果默认值为true的话,删除的时候还是先取得数据,删除,然后再取得所有数据,如果默认为false的话,在第一次打开页面的时候会不取数据。现在郁闷死了,不知道那些用jsf做工程的是怎么处理的。
2.2list放到savestate是不可能,数据太大,影响性能,如果只能用这种方式处理,还不如不用jsf。

感觉jsf的表格总是在自作聪明的想帮你做所有的事,像上面说的估计就是jsf在判断你点击了那一行,所以才要再次取得数据。你老老实实的做好你的局部刷新页面就好了(这是jsf唯一吸引我的地方),管那么多干什么啊,我点哪一行我自己知道,不需要你来告诉我。
Global site tag (gtag.js) - Google Analytics