【问题标题】:Integrating jsTree with Treemodel将 jsTree 与 Treemodel 集成
【发布时间】:2017-05-18 17:30:40
【问题描述】:

我是一个完整的javascript新手,如何将前端的jsTree与node.js中的后端服务集成在一起。 后端是使用 Treemodel 库 (http://jnuno.com/tree-model-js/) 编写的。具有附加功能,例如

function getChildren(x)
{
    var result=[];
    if(x.hasChildren())
    {
        for(i=0;i<x.children.length;i++)
        {
            result.push(x.children[i].model);
        }
    }
    return result;
}

function expandAll(node) {
    console.log(getChildren(node));
    for (var t = 0; t < node.children.length; t++) {
        if (node.children[t].hasChildren()) {
            expandAll(node.children[t]);
        }
    }
}

我的数据最初是纯文本格式:

var items = [
    {'id': 2, 'parentid': 1, 'title': "Delhi"},
    {'id': 3, 'parentid': 2, 'title': "CP"},
    {'id': 4, 'parentid': 2, 'title': "Saket"},
    {'id': 1, 'parentid': 0, 'title': "India"},
    {'id': 5, 'parentid': 1, 'title': "Mumbai"},
    {'id': 6, 'parentid': 5, 'title': "Andheri"},
    {'id': 7, 'parentid': 5, 'title': "Worli"},
    {'id': 8, 'parentid': 7, 'title': "Wankhede"}
];

已通过使用带有 underscore.js 的以下代码将其转换为 JSON-

unflatten = function( array, parent, tree ){

    tree = typeof tree !== 'undefined' ? tree : [];
    parent = typeof parent !== 'undefined' ? parent : { id: 0 };

    var children = _.filter( array, function(child){ return child.parentid == parent.id; });

    if( !_.isEmpty( children )  ){
        if( parent.id == 0 ){
           tree = children;   
        }else{
           parent['children'] = children
        }
        _.each( children, function( child ){ unflatten( array, child ) } );                    
    }

    return tree;
}

items = unflatten(items); 

我将在前端使用 AJAX 延迟加载实现一个树形结构,类似于:http://thejackalofjavascript.com/file-browser-with-jstree-angularjs-and-expressjs/

我只需要帮助了解如何使用 TreeModel 实现 jsTree,以及如何使用后端实现的 getChildren 方法实现延迟加载。

谢谢

【问题讨论】:

    标签: jquery angularjs node.js jstree treemodel


    【解决方案1】:

    这是一个使用restify 服务器的简单示例。

    1) 使用以下package.json 文件创建一个项目文件夹:

    {
      "name": "remote-tree",
      "version": "1.0.0",
      "main": "server.js",
      "scripts": {
        "start": "node server.js"
      },
      "dependencies": {
        "flat-to-nested": "1.0.2",
        "restify": "4.3.0",
        "tree-model": "1.0.6"
      }
    }
    

    2) 运行npm install

    3) 创建节点脚本server.js,内容如下

    let restify = require('restify'),
      TreeModel = require('tree-model'),
      FlatToNested = require('flat-to-nested'),
      flatToNested = new FlatToNested({parent: 'parentid'}),
      tree = new TreeModel()
    
    let items = [
      {id: 0},
      {id: 2, parentid: 1, title: 'Delhi'},
      {id: 3, parentid: 2, title: 'CP'},
      {id: 4, parentid: 2, title: 'Saket'},
      {id: 1, parentid: 0, title: 'India'},
      {id: 5, parentid: 1, title: 'Mumbai'},
      {id: 6, parentid: 5, title: 'Andheri'},
      {id: 7, parentid: 5, title: 'Worli'},
      {id: 8, parentid: 7, title: 'Wankhede'}]
    
    let root = tree.parse(flatToNested.convert(items))
    
    let server = restify.createServer()
    
    server.get('/public', restify.serveStatic({
      directory: './public',
      default: 'index.html',
      file: 'index.html'
    }))
    
    server.get('/children/:id', (req, res, next) => {
      let id = req.params.id
      let node = root.first(node => node.model.id == id)
      if (node && node.hasChildren()) {
        res.send(200, node.children.map(child => ({
          id: child.model.id,
          text: child.model.title,
          children: child.hasChildren()
        })))
      } else {
        res.send(404)
      }
    
      return next()
    })
    
    server.listen(8080)
    

    4) 创建一个public 文件夹来放置您的index.html 文件

    5) 在public 文件夹中创建index.html 文件,内容如下:

    <!DOCTYPE html>
    <html>
    <head>
      <title>remote-tree</title>
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
    </head>
    <body>
      <div id="jstree"></div>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
      <script>
        $(() => $('#jstree').jstree({
          core: {
            data: (node, cb) => {
              let id = node.id === '#' ? 0 : node.id;
              fetch(`/children/${id}`).then(response => response.json()).then(children => cb(children))
            }
          }
        }))
      </script>
    </body>
    </html>
    

    6) 运行npm start 并浏览到localhost:8080/public

    【讨论】:

    • 感谢您的快速响应!只是想知道是否有任何特殊原因使用 restify 而不是 express,因为我将使用 express 生成器来获取一般项目结构。另外,这是否意味着我不需要使用我编写的 getChildren/expandAll 方法(我之所以这么写是因为 Treemodel 中没有),而 jsTree 会处理它吗? PS:我喜欢树模型。
    • @howyoulikemenow 您也可以使用 express,我不知道 restify 也不知道 express,这只是一种快速获取 rest 资源并提供 index.html 的方法。支持 expandAll 功能需要更多代码。
    • 我知道这有点跑题了,但是 node.js 中是否需要 expandAll 功能,jsT​​ree 不会像 jstree.com/api/#/?f=open_all([obj, animation, original_obj])> 这样的方法能应付吗?
    • @howyoulikemen现在它应该在节点中没有 expandAll 的情况下工作,但它会导致比自定义端点更多的请求。这取决于树的深度。
    猜你喜欢
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    相关资源
    最近更新 更多