howto:Extjs+SpringRoo 创建 可编辑树 第一部分 Jimmy

需求分析:在权限管理和组织结构管理中都有树状结构的页面应用。如网站菜单中,会有一级菜单,二级菜单;在组织结构中有,一个大部门会有多个小部门,还会有二级部门和三级部门。这样的数据结构我们称之为 无限级分类树。在实际项目中,这样的页面结构都有广泛的应用。今天我们就是用SpringRoo和Extjs结合,来实现一个Menu树的管理功能。
系统设计及实现思路:对于树状结构 通过数据库和orm映射,可以有多种方法实现。比较简单的有单表联合,或者是MPTTree。今天我们介绍最简单的单表联合的方法来实现。
我们先来看看如何用单表是如何联合的。
1、设计数据结构
 
(这里应该显示ER图)Node实体类表明树中的节点,通过一个对多的关系和自身关联。所以任何一个Node都可以有一个父节点Parent和多个子节点Children。
2、在Extjs的demo中寻找合适的例子。(这里介绍如何使用EasyPhp)
 
经过查找,觉得是用这个例子,原因一它是用JSON 做异步加载,这和我们的需求很像。
 2.1阅读demo代码,修改数据结构。我们设计的数据结构还不能满足发的的需求,通过阅读上面这个例子,我发现为了实现效果,还需要增加一些其他的字段。
(注:这里你需要了解treepanel工作的原理,这个可以通过阅读页面的JS文件和文档学习)
我使用httpwatch来截取页面发送的异步请求,来确定页面加载的JSON结构的。我们来看下图:
 
JSON的结构是:
         {"text":"CompositeElement.js","id":"src\/core\/CompositeElement.js","leaf":true,"cls":"file"}  这样的。
通过阅读文档我们可以知道:
         text:是节点的标题,
         id :是节点的标识
         leaf:标示该节点是否还有子节点,为true 是无子节点,false是有子节点
         cls:是节点的图标
3、键入SpringRoo命令,实现Crud。
我们直接看创建实体类的命令:
entity --class ~.domain.node
field string --fieldName text --notNull 
field boolean --fieldName leaf  
field set --fieldName children --type ~.domain.Node --cardinality ONE_TO_MANY --mappedBy parent
接下来我们创建需要的页面,同时增加JSON访问的能力,命令是:
web mvc all --package ~.web
json all
注:现在创建的代码还不能直接使用,我们还需要手工添加parent 字段,同时给leaf字段增加初始值。我使用的是IDE添加的:
 
保存后Roo会自动更行其他文件。
现在我们来浏览一下效果。
这是表单:
 
这是列表:
 
5、对生成的Crud进行修改,以满足我们的页面的需要。我们可以看到Leaf这个字段。
它的含义是如果该节点没有子节点时,它就是一个叶子值为true,反之为false。
每次增加节点时都要对父节点进行修改,那就太麻烦了。而且容易出错。这里我们通过AOP拦截,
Node.persist和Node.remove两个方法来实现自动修改。代码如下:
 
@RooWebScaffold(path = "nodes", formBackingObject = Node.class)
@RequestMapping("/nodes")
@Controller
@Aspect
public class NodeController {
    @AfterReturning(value = "execution(* com.pccw.finance.domain.Node.persist(..))")
    public void leafpersist(JoinPoint joinPoint)
    {
        Node n = (Node)joinPoint.getThis();
        if(n.getParent() != null){
            Node p = n.getParent();
            if (p.getLeaf() == true){
                p.setLeaf(false);
                p.persist();
            }
        }
    }
    @AfterReturning(value = "execution(* com.pccw.finance.domain.Node.remove(..))")
    public void leafremove(JoinPoint joinPoint)
    {
        Node n = (Node)joinPoint.getThis();
        if(n.getParent() != null){
            Node p = n.getParent();
            if (p.getChildren().isEmpty()){
                p.setLeaf(true);
                p.persist();
            }
        }
    }
}
红色的为后添加的。通过上面两段代码就可以实现,自动维护
leaf字段状态了
(都四点了,今天先到这吧)
posted on 2012-03-24 22:57  Jimmy_June  阅读(290)  评论(0编辑  收藏  举报