0

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

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

一切看起来都很好,直到需要更新商店 - 显示错误 - 移动的项目未显示在正确的位置。

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 - 我可以在这方面投入更多时间,但我不想这样做。选择不同的方法 - 使用传统输入并提供只读树视图。

4

1 回答 1

1

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

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 函数的 hack 还不够)。一种选择是使用已弃用的 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。你也可以参考这个例子

于 2016-10-16T19:45:16.533 回答