Dojo Tree:从*unformatted*json到预期格式的桥接

dmi*_*idz 1 dojo

我是Dojo(1.7)的新手,我对AMD装载机和全球哲学感到非常兴奋,然后我觉得我已经红了几十个文档并且搜索了很多,我的大脑开始烧烤,我仍然无法理解并执行一些操作:我想显示任何类型的JSON 的dijit.Tree ,是的,就像JSON编辑器,因为我还使用持久性JSON文件来存储少量数据(不仅仅用于GET /.../传输).这是我的期望:

  • 示例JSON: {"infos":{"address":"my address","phone":"my phone"},"insurance":{"forks":[14,53,123],"prices":[5,8,"3%"]}}
  • 显示任何JSON的不同变量:root子是根json变量,子L1是根变量等等...并且在json变量类型(String,Number,Object,Array)上我还会显示相应的图标
  • 不必解析整个json并在一个很大的时间内对其进行格式化,例如首先要显示根节点,然后以良好格式化的子节点为例进行getChildren方法,因此它在expando上逐步完成(就像懒惰一样)加载).我已经使用javascript创建了自己的Trees类,更灵活的方式是我给构造函数一个dataRoot,一个renderItem(dataItem,domItem)和一个getChildren(dataItem),所以我可以执行并返回我想要的所有内容,仅限Tree只在需要时才执行渲染,Tree不知道数据结构也没有修改它,但我不确定为什么dijit.Tree需要一种如此限制的构建方式...

这是我的最后一次尝试,它可能完全不是正确的方式,(也许我必须继承)但据我所知,我需要玩3个类(dojo存储,树模型和树小部件),但首先它似乎模型无法获取根节点,请检查我的不同代码注释.那么,请问有没有耐心的人可以给我一个简单的例子,有一些明确的解释(是的,我有点要求),至少是构造函数选项的正确必要变量列表,我需要开始显示我的一个很好的树视图json文件,有这么多我完全失去了,非常感谢!

...
// before there is the AMD part that load the needed things
Xhr.get({ url:'data/file.json', handleAs:'json',
    load: function(data){
        console.log('xhr.loaded : ', data);// got my javascript object from the json string
        var store = new ItemFileReadStore({// is it the right store I need ??
            // or the Memory store ?
            // assuming later I'll need to save the data changes 
            rootId : 'root',// 
            rootLabel : 'Archive',// useless ? isn't it the model responsability ?
            data : {id:'root', items:[data]}// trying to give a root node well formatted
        });
        var model = new TreeStoreModel({
            store : store,
            getChildren : function(obj){
                // firstly here it seems the root is not found
                // I got a 'error loading root' error
                // what is missing in my instanciations ??
                // what is exactyly the type of the 1st arg : a store ?
                console.log('getChildren : ', this.get(obj.id));
            },
            mayHaveChildren : function(){
                console.log('mayHaveChildren ', arguments);
                return true;
            }
        });
        var tree = new Tree({
            model: model
        }, domId);
        tree.startup();
    }
});
Run Code Online (Sandbox Code Playgroud)

phu*_*ick 5

我的解决方案基于将商店连接到树的dojo/store/Memory灵感:

在此输入图像描述

您可以在http://egoworx.com/上找到现场演示,或从dropbox下载完整的源代码.

现在代码.第一dojo/store/Memory:

var data =  {"infos":{"address":"my address","phone":"my phone", "gift": false, "now": new Date()},"insurance":{"forks":[14,53,123],"prices":[5,8,"3%"]}};

var store = new Memory({

  data: data,

  mayHaveChildren: function(object) {
    var type = this.getType(object);
    return (type == "Object" || type == "Array");
  },

  getChildren: function(object, onComplete, onError) {
    var item = this.getData(object);
    var type = this.getType(object);
    var children = [];

    switch(type) {
      case "Array":
        children = item;
        break;
      case "Object":
        for (i in item) {
          children.push({label: i, data: item[i]});
        }
        break;
    }
    onComplete(children);
  },

  getRoot: function(onItem, onError) {
    onItem(this.data);
  },

  getLabel: function(object) {
    var label = object.label || object + "";
    var type = this.getType(object);

    switch(type) {
      case "Number":
      case "String":
      case "Boolean":
      case "Date":
        var data = this.getData(object);
        if (data != label) {
          label += ": " + this.getData(object);
        }
    }

    return label;
  },

  getData: function(object) {
    if (object && (object.data || object.data === false) && object.label) {
      return object.data;
    }
    return object;
  },

  getType: function(object) {
    var item = this.getData(object);
    if (lang.isObject(item)) {
      if (lang.isArray(item)) return "Array";
      if (lang.isFunction(item)) return "Function";
      if (item instanceof Date) return "Date";
      return "Object";
    }

    if (lang.isString(item)) return "String";
    if (item === true || item === false) return "Boolean";
    return "Number";
  },

  getIconClass: function(object, opened) {
    return this.getType(object);
  }    
});
Run Code Online (Sandbox Code Playgroud)

请注意我在数据中添加了布尔值日期类型.

dijit/Tree 基于这家商店:

var tree = new Tree({
    model: store,
    persist: false,
    showRoot: false,
    getIconClass: function(object, opened) {
      if (lang.isFunction(this.model.getIconClass)) {
        return this.model.getIconClass(object, opened);
      }
      return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf";
    }
  }, "placeholder");

tree.startup();
Run Code Online (Sandbox Code Playgroud)

最后是一个显示数据类型图标的样式表:

.dijitTreeIcon {
  width: 16px;
  height: 16px;  
}

.Object {
  background-image: url(http://dojotoolkit.org/api/css/icons/16x16/object.png);
}

.Array {
  background-image: url(http://dojotoolkit.org/api/css/icons/16x16/array.png);
}

.Date {
  background-image: url(http://dojotoolkit.org/api/css/icons/16x16/date.png);
}

.Boolean {
  background-image: url(http://dojotoolkit.org/api/css/icons/16x16/boolean.png);
}

.String {
  background-image: url(http://dojotoolkit.org/api/css/icons/16x16/string.png);
}

.Number {
  background-image: url(http://dojotoolkit.org/api/css/icons/16x16/number.png);
}
Run Code Online (Sandbox Code Playgroud)

因为我目前在中国,所以我无法访问jsFiddle,但我会在返回欧洲时将代码放在上面并在此处发布链接.