angular-bootstrap-nav-tree icon indicating copy to clipboard operation
angular-bootstrap-nav-tree copied to clipboard

How to dynamically and efficiently populate the angular tree nodes

Open tron88888 opened this issue 6 years ago • 1 comments

So let's say I have a list of filepaths in an Arraylist.

Arraylist<String> list = new Arraylist<String>();
list.add("folder1 > folder2 > folder3 > file1.jpg");
list.add("folder1 > folder2 > folder3 > file2.jpg");

Are there anyway to efficiently transform this list of filepaths into the node structure at my Java side.

Here's what I did at my Java API side.

@RequestMapping(value = "/retrieveTreeNodes", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Object[] retrieveTreeNodes() {
       JSONArray jsonArray = new JSONArray();
       int index=0;
       for(int i=0; i<list.size();i++){
            jsonArray.put(function(list.get(i), index, jsonArray));
       }
       JacksonHandle jacksonHandle = new JacksonHandle();
       try{
           return jacksonHandle.getMapper().readValue(jsonArray.toString(), Object[].class);
        }catch(Exception e){}
}

public JSONObject function(String str, int index, JSONArray jsonArray) {
	String[] paths = str.split(">");						
	return pathsToJSONObject(paths, index, jsonArray);		
}
	
public JSONObject pathsToJSONObject(String[] paths, int index, JSONArray jsonArray) {
	JSONObject jsono = new JSONObject();
		
	if(paths.length==1) {			
		jsono.put("name", paths[0].trim());
		jsono.put("id", index); index++;
                return jsono;
	} else {
		jsono.put("name",paths[0].trim());
		jsono.put("id", index); index++;			
		jsono.append("children", 
                    pathsToJSONObject(ArrayUtils.removeElement(paths,paths[0]),index,jsonarrayNodes));			
		return jsono;
	}
}

Eventually this Object[] will be parsed into my Angular website example:

component.ts as

this.restclient.getjson('/api/retrieveTreeNodes').subscribe(nodes=>{
           this.nodes = nodes;
           this.tree.treeModel.update();
          });

component.html as

<tree-root #tree [nodes]="nodes"></tree-root>

The Object expected to be returned:

[
 {
    "children": [
      {
        "children": [
          {
            "children": [
              {
                "name": "file1.jpg",
                "id": 3
              },
              {
                "name": "file2.jpg",
                "id": 4
              }
            ],
            "name": "folder3",
            "id": 2
          }
        ],
        "name": "folder2",
        "id": 1
      }
    ],
    "name": "folder1",
    "id": 0
  }
]

This is the expected result:

>folder1
    >folder2
        >folder3
           >file1.jpg
           >file2.jpg

But this is the actual Object[] returned:

[
 {
    "children": [
      {
        "children": [
          {
            "children": [
              {
                "name": "file1.jpg",
                "id": 3
              }              
            ],
            "name": "folder3",
            "id": 2
          }
        ],
        "name": "folder2",
        "id": 1
      }
    ],
    "name": "folder1",
    "id": 0
  },
  {
    "children": [
      {
        "children": [
          {
            "children": [
              {
                "name": "file2.jpg",
                "id": 7
              }              
            ],
            "name": "folder3",
            "id": 6
          }
        ],
        "name": "folder2",
        "id": 5
      }
    ],
    "name": "folder1",
    "id": 4
  }
]

and This is the actual result:

>folder1
    >folder2
        >folder3
           >file1.jpg
>folder1
    >folder2
        >folder3
           >file2.jpg

Where did I go wrong... what else should I do...

Adding on, what if one day I'll have to add a few new files to the list of filepaths e.g

list.add("folder1 > folder2 > file3.jpg");
list.add("folder4 > folder5 > folder6 > folder7 > file4.jpg");

tron88888 avatar Oct 26 '17 09:10 tron88888

First, I think you should post your questions on StackOverflow rather than here.

Looks like the problem is in your Java code. Maybe you should mark each item's level when parsing the list items. E.g.: For the list item "folder1 > folder2 > folder3 > file1.jpg", you should mark "folder 1" a level 0 branch, mark the "folder 2" a level 1 branch, and so on. Also you might need to record its parent node's id. Then, when you generating the JSON, you can add branches according to its level and parent.

boris1993 avatar Nov 09 '17 03:11 boris1993