0

children我有一个使用树结构的 js 应用程序,其中节点的子节点作为数组存储在它的属性中。数据从 MySQL 数据库中读取,树结构构建在 php 后端。然后一切都作为 JSON 发送:

[
    {
        id: 1,
        children: [
            {
                id: 11
            },
            {
                id: 12
            }
        ]
    },
    {
        id: 2
    },
    {
        id: 3
    }
]

这是我正在使用的 PHP 脚本。它可以分为4个阶段:

  • 首先,我通过它们的 id 创建一个关联的节点数组
  • 然后我创建另一个数组,只取第一级的节点(没有定义 parentId)
  • 接下来我递归遍历第一个数组检查 id 和 parentId 并构建我的树
  • 最后我将输出关联数组重写为索引数组

这是整个来源:

q = 'SELECT * FROM tasks';
$r = mysql_query($q);
$tasks = array();

//1.
while ($e = mysql_fetch_assoc($r)){
    $tasks[$e['Id']] = $e;
}

$sortedArray = array();

//2. get first level with no parent
foreach($tasks as $k => $v){
    if($v['parentId'] == 'null'){
        $sortedArray[$k] = $v;
        unset($tasks[$k]);
    }
}

//3. calls findChildren for first level nodes
function getChildren(array & $a1, array & $a2){
    foreach($a1 as $k => $v){
        findChildren($v, $a2, $k);      
    }
}

//recursive method checking if record's parent is already in the `sortedArray`.
//if yes, it's added to parent's `children` array. Otherwise it tries to
//find the parent in the node`s `children` array
function findChildren($rec1, array & $a2, $key){

    foreach($a2 as $k => $v){
        if($rec1['parentId'] == $v['Id']){
            $a2[$k]['children'][$rec1['Id']] = $rec1;
            unset($tasks[$key]);
        } else {
            if (isset($v['children'])){
                findChildren($rec1, $a2[$k]['children'], $key);
            }
        }
    }
}

//4. after `findChildren` `sortedArray` is an associative array, which
//is not valid for JSON
function makeIndexed(array & $arr, array & $par = null){
    if(is_null($par)){
        $arr = array_values($arr);
    } else {
        $par['children'] = array_values($arr);
    }

    for($i=0; $i<count($arr); $i++) {   
        $temp = @$arr[$i]['children'];
        if(isset($temp)) {
            makeIndexed($arr[$i]['children'], $arr[$i]);
        }       
    }
}

getChildren($tasks, $sortedArray);

makeIndexed($sortedArray);

echo json_encode($sortedArray);

现在我的目标是在 Java 后端重新创建这种行为。现在,我只是从 Hibernate 查询中获得了一个包含所有事件的平面列表结构:

public static Map<String,Object> getEvents() {

    DetachedCriteria criteria = DetachedCriteria.forClass(Event.class);

    return mapOk(hibernateTemplate.findByCriteria(criteria));
}

public static Map<String,Object> mapOK(List<Event> events){

    Map<String,Object> modelMap = new HashMap<String,Object>(2);
    modelMap.put("data", events);
    modelMap.put("success", true);

    return modelMap;
}

如何解决这个问题?自从我上次使用 Java 以来已经有一段时间了,而且我从未将它用于 Web 编程,所以我不确定从哪里开始以及应该采用什么方法。也许这可以以某种方式自动化?

4

1 回答 1

1

不知道为什么有人-1'ed我的问题,但这是我想出的:

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.*;

import org.com.model.Task;

@Component
public class ReturnTasks {

    private static JSONObject sortedByParentTasks = null;
    private static JSONArray tasksTree = null;
    private static JSONObject taskChildrenObject;

    /**
     * Generates JSON String to return in the modelAndView
     * @param events
     * @return
     * @throws JSONException 
     * @throws IOException 
     * @throws JsonMappingException 
     * @throws JsonGenerationException 
     */

    public static String mapOK(List<Task> events) throws JSONException, JsonGenerationException, JsonMappingException, IOException{
        tasksTree = null;
        tasksTree = new JSONArray();
        sortedByParentTasks = null;
        sortedByParentTasks = new JSONObject();
        tasksTree = makeTree(events);

        return tasksTree.toString();
    }

    private static JSONArray makeTree(List<Task> list) throws JSONException, JsonGenerationException, JsonMappingException, IOException{

        Iterator<Task> listIterator = list.iterator();
        String parentId;

        while(listIterator.hasNext()){
            Task task = listIterator.next();
            JSONArray equalParentId;
            parentId = ""+task.getParentId();
            String json = new ObjectMapper().writeValueAsString(task);
            JSONObject taskJSON = new JSONObject(json);

            if (sortedByParentTasks.has(parentId)){
                sortedByParentTasks.accumulate(parentId, taskJSON);
            } else {
                equalParentId = new JSONArray();
                equalParentId.put(taskJSON);
                sortedByParentTasks.put(parentId, equalParentId);
            }
        }

        addNodes(sortedByParentTasks.getJSONArray("null"));

        return tasksTree;
    }

    private static void addNodes(JSONArray nodes) throws JSONException{
        for(int i=0, l=nodes.length(); i<l; i++){
            taskChildrenObject = nodes.getJSONObject(i);
            listHierarchy(taskChildrenObject);
            tasksTree.put(taskChildrenObject);
        }
    }

    private static void listHierarchy(JSONObject task) throws JSONException{
        JSONArray childrenArray = new JSONArray();
        JSONArray childNodes = new JSONArray();

        try {
            childNodes = sortedByParentTasks.getJSONArray(""+task.get("Id"));
        }catch(JSONException e){} 

        if (childNodes.length() > 0){
            for (int i=0, l=childNodes.length(); i<l; i++) {
                JSONObject childObject = childNodes.getJSONObject(i);
                childrenArray.put(childObject);
                try{
                    task.put("children", childrenArray);
                    task.put("leaf", false);
                }catch(JSONException e){}

                listHierarchy(childObject);
            }           
        }
    }

    /**
     * Generates modelMap to return in the modelAndView in case
     * of exception
     * @param msg message
     * @return
     */
    public static String mapError(String msg){

        Map<String,Object> modelMap = new HashMap<String,Object>(2);
        modelMap.put("message", msg);
        modelMap.put("success", false);

        return modelMap.toString();
    } 
}
于 2012-12-19T01:17:40.000 回答