在Dijit树中移动节点

时间:2016-10-16 02:46:46

标签: dojo dijit.tree

我使用树作为输入工具,允许用户组织类别。

我希望用户能够在顶层移动节点,特别是在同一父节点下重新排序它们。

一切都很好看,直到商店更新时间 - 显示错误 - 移动的商品没有显示在正确的位置。

require([
  "dojo/aspect",
  "dojo/store/Memory",
  "dojo/store/Observable",
  "dijit/Tree",
  "dijit/tree/ObjectStoreModel",
  "dijit/tree/dndSource",
  "dojo/domReady!"
], function(aspect, Memory, Observable, Tree, ObjectStoreModel, dndSource) {

  var observableStore, model;
  var memoryStore = new Memory({
    data: [{
      "id": 10,
      "position": 0,
      "name": "top",
      "parent": null
    }, {
      "id": 19,
      "position": 18,
      "name": "Audio",
      "parent": 10
    }, {
      "id": 23,
      "position": 19,
      "name": "Monitors",
      "parent": 10
    }, {
      "id": 20,
      "position": 20,
      "name": "Communication",
      "parent": 10
    }, {
      "id": 21,
      "position": 28,
      "name": "Video",
      "parent": 10
    }, {
      "id": 18,
      "position": 29,
      "name": "Camera",
      "parent": 10
    }, {
      "id": 22,
      "position": 40,
      "name": "Five",
      "parent": 21
    }, {
      "id": 24,
      "position": 60,
      "name": "Networking",
      "parent": 21
    }, {
      "id": 25,
      "position": 70,
      "name": "Toasters",
      "parent": 18
    }],
    mayHaveChildren: function(object) {
      var children = this.store.getChildren(object);
      return children.length > 0;
    },
                    getChildren: function (object) {
                    return this.query({parent: object.id});
                }
  });

  observableStore = new Observable(memoryStore);

  model = new ObjectStoreModel({
    store: observableStore,
    query: {
      name: "top"
    }
  });

  aspect.around(memoryStore, "put", function(originalPut) {
    // To support DnD, the store must support put(child, {parent: parent}).
    // Since memory store doesn't, we hack it.
    // Since our store is relational, that just amounts to setting child.parent
    // to the parent's id.
    return function(obj, options) {
      if (options && options.parent) {
        obj.parent = options.parent.id;
      }
      return originalPut.call(memoryStore, obj, options);
    }
  });

  var tree =new Tree({
    model: model,
    dndController: dndSource,
    betweenThreshold: 5,
    showRoot: false,
    persist: false
  }, "category-tree").startup();


});

JSFiddle

https://bugs.dojotoolkit.org/ticket/18142 - 我可以投入更多时间,但我不想。选择不同的方法 - 使用传统输入并提供只读树视图。

1 个答案:

答案 0 :(得分:1)

在使用Observable包装之前,您需要将方面放在商店的put函数周围。使用您的代码Observable无法访问替换的put函数。如果您仔细复制example,它将起作用。

require([
  "dojo/aspect",
  "dojo/store/Memory",
  "dojo/store/Observable",
  "dijit/Tree",
  "dijit/tree/ObjectStoreModel",
  "dijit/tree/dndSource",
  "dojo/domReady!"
], function(aspect, Memory, Observable, Tree, ObjectStoreModel, dndSource) {

  var observableStore, model;
  var memoryStore = new Memory({
    data: [{
      "id": 10,
      "position": 0,
      "name": "top",
      "parent": null
    }, {
      "id": 19,
      "position": 18,
      "name": "Audio",
      "parent": 10
    }, {
      "id": 23,
      "position": 19,
      "name": "Monitors",
      "parent": 10
    }, {
      "id": 20,
      "position": 20,
      "name": "Communication",
      "parent": 10
    }, {
      "id": 21,
      "position": 28,
      "name": "Video",
      "parent": 10
    }, {
      "id": 18,
      "position": 29,
      "name": "Camera",
      "parent": 10
    }, {
      "id": 22,
      "position": 40,
      "name": "Five",
      "parent": 21
    }, {
      "id": 24,
      "position": 60,
      "name": "Networking",
      "parent": 21
    }, {
      "id": 25,
      "position": 70,
      "name": "Toasters",
      "parent": 18
    }],
    mayHaveChildren: function(object) {
      var children = this.store.getChildren(object);
      return children.length > 0;
    },
                    getChildren: function (object) {
                    return this.query({parent: object.id});
                }
  });

  aspect.around(memoryStore, "put", function(originalPut) {
    // To support DnD, the store must support put(child, {parent: parent}).
    // Since memory store doesn't, we hack it.
    // Since our store is relational, that just amounts to setting child.parent
    // to the parent's id.
    return function(obj, options) {
      if (options && options.parent) {
        obj.parent = options.parent.id;
      }
      return originalPut.call(memoryStore, obj, options);
    }
  });

  observableStore = new Observable(memoryStore);

  model = new ObjectStoreModel({
    store: observableStore,
    query: {
      name: "top"
    }
  });


  var tree =new Tree({
    model: model,
    dndController: dndSource,
    showRoot: false,
    persist: false
  }, "category-tree").startup();


});

JSFiddle的一个分支。

更新:上述解决方案不支持betweenThreshold选项(能够将项目放在其他项目之间而不是将其作为另一项目的子项)。即使是官方参考指南示例也不起作用。这需要一个适当支持项目定位的商店(MemoryStore不会,而put函数的黑客攻击还不够)。一种选择是回到不推荐使用的dojo / data / ItemFileWriteStore。

require([
  "dojo/data/ItemFileWriteStore",
  "dijit/Tree",
  "dijit/tree/TreeStoreModel",
  "dijit/tree/dndSource",
  "dojo/domReady!"
], function(ItemFileWriteStore, Tree, TreeStoreModel, dndSource) {

  var model;

  var categories = {
    identifier: 'id',
    label: 'name',
    items: [
        { id: '0', name:'Foods', numberOfItems:1, children:[ {_reference: '1'},  {_reference: '2'},  {_reference: '3'} ] },
            { id: '1', name:'Fruits', numberOfItems:1, children:[ {_reference: '4'} ] },
                { id: '4',name:'Citrus', numberOfItems:1, items:[ {_reference: '5'} ] },
                    { id: '5', name:'Orange'},
        { id: '2', name:'Vegetables', numberOfItems:0},
        { id: '3', name:'Cereals', numberOfItems:0}
    ]
};
  var memoryStore = new ItemFileWriteStore({data: categories});

  var model = new TreeStoreModel({store: memoryStore, query:{id: "0"}});


  var tree =new Tree({
    model: model,
    dndController: dndSource,
    betweenThreshold: 5,
    showRoot: false,
    persist: false
  }, "category-tree").startup();


});

这是另一个JSFiddle。您也可以参考此example