随笔 - 170  文章 - 536  trackbacks - 0
<2006年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

我参与的团队

随笔分类(103)

搜索

  •  

积分与排名

  • 积分 - 412357
  • 排名 - 135

最新评论

阅读排行榜

改变Tree中的内容

(当展开树的节点时,在后台延迟加载)

在邮件列表中有很多关于这项任务的问题和讨论,我(Marcel,一个 JSF 的初学者)在这里总结一下。如果你有更好的解决方案,请更新这些文字。

在这里存在的一个问题就是我要这样把“+”图标去掉:

·         <t:tree2 ... showNav="false" ...>

然后再让文件夹图标(代表包含子节点的节点)变的可点击:

·         <h:commandLink action="#{t.toggleExpanded}" actionListener="#{navigationBacker.processAction}">

然后在 Java 代码中接受鼠标点击的事件。在 NavigationBacker.java 文件中的processAction(ActionEvent e) 方法里,我从 EJB3-persistency 中加载子结点的数据。

不好的是“+”图标变的不可见,但是我现在没有办法获取点击“+”图标的事件。

看起来在org.apache.myfaces.custom.tree2.HtmlTree.java这个文件里是通过注册了_expandControl = new HtmlCommandLink(); 从内部获取“+”的点击事件,但是我现在没有办法从我的代码中接受到这一事件。

为了导航,我使用了含有entriesTreeNode.getIdentifier() (参见:#{node.identifier}),看起来就是这个样子:

·         db_id="car_id=7,person_id=2"

这代表了后台数据库表的主键(我还没有找到一个更好的解决方案用于导航)

程序代码如下:

navigation.jsp

  <t:tree2 id="serverTree" value="#{navigationBacker.treeData}"
    var
="node" varNodeToggler="t" clientSideToggle="false" showNav="false"
    showRootNode
="false">
    
<f:facet name="project-folder">
      
<h:panelGroup>
        
<h:commandLink action="#{t.toggleExpanded}" actionListener="#{navigationBacker.processAction}">
            
<t:graphicImage value="/images/yellow-folder-open.png"
                rendered
="#{t.nodeExpanded}" border="0" />
            
<t:graphicImage value="/images/yellow-folder-closed.png"
                rendered
="#{!t.nodeExpanded}" border="0" />
        
</h:commandLink>
        
<h:commandLink action="#{navigationBacker.toViewId}"
            styleClass
="#{t.nodeSelected ? 'documentSelected':'document'}"
            actionListener
="#{navigationBacker.nodeClicked}"
            value
="#{node.description}" immediate="true">
            
<f:param name="db_id" value="#{node.identifier}" />
            
        
</h:commandLink>
        
<h:outputText value=" (#{node.childCount})" styleClass="childCount"
            rendered
="#{!empty node.children}" />
      
</h:panelGroup>
    
</f:facet>
    
<f:facet name="person-folder">
      
<h:panelGroup>

NavigationBacker.java

    /**
     * 拦截节点被展开的事件,并加载额外的数据
     * 
@param event
     * 
@throws AbortProcessingException
     
*/

    
public void processAction(ActionEvent event) throws AbortProcessingException {
            System.out.println(
"Entering processAction()");
            UIComponent component 
= (UIComponent) event.getSource();
            
while (!(component != null && component instanceof HtmlTree)) {
                    component 
= component.getParent();
            }

            
if (component != null{
                    HtmlTree tree 
= (HtmlTree) component;
                    TreeNodeBase node 
= (TreeNodeBase) tree.getNode();
                    
if (!tree.isNodeExpanded() && node.getChildren().size() == 0{
                        Map
<String, String> map = splitKeyValues(node.getIdentifier()); // 一些辅助代码,用于将 "car_id=7" 或 "car_id=7&person_id=12" 拆分开
                        this.car_id = map.get("car_id");
                        
if (this.car_id != null{
                            appendPersonsNodes(node); 
// 参见下面的例子
                        }

                        
this.person_id = map.get("person_id");
                        
if (this.person_id != null{
                            appendLicensesNodes(node); 
// 没有显示
                        }

                    }

            }

    }


    
/** 把当前car_id下的Person子结点加入导航中 */
    
private void appendPersonsNodes(TreeNodeBase carDetailNode) {
        VariableResolver resolver 
= FacesContext.getCurrentInstance()
        .getApplication().getVariableResolver();
        PersonsTable personsTable 
= (PersonsTable) resolver
                .resolveVariable(FacesContext.getCurrentInstance(),
                        
"personsTable");
        List
<Person> personsList = personsTable.getCarPersons();
        
for (Person o : personsList) {
            List
<TreeNodeBase> list = carDetailNode.getChildren();
            list.add(
new TreeNodeBase("person-folder", o.getDescription(),
                            
"person_id=" + o.getPersonId(), true));
        }

        System.out.println(
"NavigationBacker fetched " + personsList.size() + " Persons for carId=" + this.car_id);
    }


这里有一段辅助代码用于从 h:commandLink 中获取 f:param 用于多种用途。

    /**
     * 当 JSF 组件 h:commandLink 包含有 f:param 成员, 这些 name-value 对被放到 
* request 参数表中供后面的action handler使用。不幸的是,这样的用法不能用在
* h:commandButton上。我们没有办法把通过 button 来传递这些参数。
     *
     * 因为 Action Listeners 可以保证在 Action 方法前被执行到,所以 Action Listeners 
* 可以调用该方法更新 Action 方法所需要的任何上下文。
     *
     * From 
http://cvs.sakaiproject.org/release/2.0.0/
     * sakai2/gradebook/tool/src/java/org/sakaiproject/tool/gradebook/jsf/FacesUtil.java
     * Educational Community License Version 1.0
     
*/

    
public static final Map getEventParameterMap(FacesEvent event) {
        Map
<String, String> parameterMap = new HashMap<String, String>();
        List children 
= event.getComponent().getChildren();
        
for (Iterator iter = children.iterator(); iter.hasNext();) {
            Object next 
= iter.next();
            
if (next instanceof UIParameter) {
                UIParameter param 
= (UIParameter) next;
                parameterMap.put(param.getName(), 
"" + param.getValue());
            }

        }

        
//System.out.println("parameterMap=" + parameterMap);
        return parameterMap;
    }


注:在上面的例子里,backing bean都存放于 session 作用域里,可以在WEB-INF/examples-config.xml 中进行配置。

 

很多朋友和我交流了一些有关 Tree2 的问题,我把一些大家经常碰到的问题拿出来,希望刚开始学习的朋友能够避免再犯一些这样的错误。

1.首先就是关于 myfaces 包的问题,Myfaces 1.1.1 release 版本的 Tree2 是有 bug 的,大概在十一月份的时候修正了大部分问题,但是由于这以后并没有 release 版本出来,所以大家可以使用一些较新一点的 Nightly Build,可以去这里找找http://cvs.apache.org/builds/myfaces/nightly/ ,不过从元旦后似乎改用了 Maven 后还没有一个 Build 出来,我手上有一个12.30 Build的版本,如果需要的话可以和我联系。因为这些 Nightly Build 不确定可能还会有其它的一些问题,所以用的时候要慎重一点。

2. 有些朋友就直接把代码贴上去用,会碰到一些诸如点击没有反应或者图标显示不出来的问题,很多时候是因为没有加上MyFaces' Extensions Filter,相关的内容可以参考我前面写的http://www.blogjava.net/steady/archive/2005/11/17/20170.html

希望这两篇介绍 Tree2 的文章能给大家一些新的认识,今后也会努力拿出更多更好的东西来和大家分享。

posted on 2006-01-13 19:28 steady 阅读(3064) 评论(1)  编辑  收藏 所属分类: JSF & Myfaces

FeedBack:
# re: 解析Tree2(二)  2007-01-19 12:45 lion
怎样保持tree2的当前状态,在下一个页面中直接显示当前页面中tree2的展开的状态。  回复  更多评论
  

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


网站导航: