复杂 JSON 结构 + Dojo 选择

Complex JSON structure + Dojo Selects

我有一个数据结构,但我不知道如何正确管理它。 我必须使用Dojo,所以我选择JSON来解决这个问题。 我说的结构在这个 post 的底部。看下文之前先去看看吧

问题:我必须有 3 Selects。第一个 select 将包含 "first level" (a, b, c)。第二个将包含 "second level" (aa, ab, ...) 等等。

每个 Select 中的数据(第一个除外)应根据上一个 Select 中选择的内容而有所不同。

例如,如果我在第一个 Select 中选择 "a",我应该只会在第二个 Select 中看到 "aa, ab, ac"。然后,如果我在第二个中选择 "ac",我应该只会看到 "aca, acb, acc"。

请注意,有些情况下没有 "third level"。在这种情况下,第三个 select 应该被隐藏(或者如果它太难管理,就留空)。

现在供参考。如果我在第一个 Select 中选择 "d",我应该只会看到 "aa, bc, ca" 作为第二个 Select 的选项。然后,如果我在第二个 Select 中选择 "cc",我应该在第三个 Select 中看到 "cca, ccb, ccc"。这当然不应该是静态的。在我的示例中,如果 "c -> cc" 子树发生变化,"d -> cc" 的内容也应该发生变化。

现在开始提问:

1) 我如何使用 Dojo 完成类似的工作?如果它是 Vanilla JS,那对我来说是显而易见的,但我不知道如何让它与所有这些对象存储和类似的东西一起工作。

2) 如何使引用与那种结构一起工作?我可以让它在一个简单的 JSON 上工作,但是当它变得如此复杂时我完全迷失了。

3) 如何呈现结构?作为单身JSON?或者我应该把它分成几个部分?

提前致谢!

a
    aa
        aaa
        aab
    ab
        aba
    ac
        aca
        acb
        acc
b
    ba
    bb
    bc
        bca
c
    ca
        caa
        cab
    cb
        cba
        cbb
    cc
        cca
        ccb
        ccc
d
    <ref to aa subtree>
    <ref to bc subtree>
    <ref to ca subtree>

嗯,你可以把它表示成一个对象,例如:

var myData = {
    a: {
        aa: ['aaa', 'aab'],
        ab: ['aba'],
        ac: ['aca', 'acb', 'acc']
    },
    b: {
        ba: null,
        bb: null,
        bc: ['bca']
    },
    c: {
        ca: ['caa', 'cab'],
        cb: ['cba', 'cbb'],
        cc: ['cca', 'ccb', 'ccc']
    },
    d: {}
};
myData.d.aa = myData.a.aa;
myData.d.bc = myData.b.bc;
myData.d.ca = myData.c.ca;

但无论如何,实施起来也相当复杂。首先,我建议编写一个函数,根据参数获取每个级别的标签。例如:

var getObjectData = function(object) {
    var data = [];
    for (var key in object) {
        if (object.hasOwnProperty(key)) {
            data.push({
                name: key,
                value: object[key]
            });
        }
    }
    return data;
};
var getData = function(obj) {
    var data = [];
    if (obj === undefined) {
        return getObjectData(myData);
    } else if (obj instanceof Array) {
        return obj.map(function(value) {
            return {
                name: value,
                value: null
            };
        });
    } else {
        return getObjectData(obj);
    }
    return data;
};

这将 return 商店内应该可用的正确数据,包含标签("a"、"b"、"c"、...)和下一级的对象结构。

那你可以这样写:

registry.byId("level1").setStore(new ObjectStore({
     objectStore: new Memory({
        data: getData(),
        idProperty: 'name'
    })
}));
var getNextLevel = function(value) {
    var data = getData(this.store.objectStore.get(value).value);
    if (this.nextLevel) {
        if (data.length > 0) {
            domStyle.set(registry.byId(this.nextLevel).domNode, "display", "inline-table");
            registry.byId(this.nextLevel).setStore(new ObjectStore({
                objectStore: new Memory({
                    data: data,
                    idProperty: 'name'
                })
            }));
        } else {
            domStyle.set(registry.byId(this.nextLevel).domNode, "display", "none");   
        }
    }
};
registry.byId("level1").on("change", getNextLevel);
registry.byId("level2").on("change", getNextLevel);

这将在值更改时检索数据(使用之前的函数),然后用该数据填充下一级的存储。

但这还不是一个完整的解决方案。因为您仍然需要进行一些初始化,但它可以让您了解如何处理这种情况。

一个例子:http://jsfiddle.net/ekoronra/