本文介绍了在Dijit树中移动节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用树作为输入工具,以允许用户组织类别.

I am using a tree as an input tool to allow the user to organize categories.

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

I would like the users to be able to move the nodes around at the top level, specifically reordering them under the same parent.

一切都很好,直到需要更新商店-显示错误-移动的项目没有显示在正确的位置.

Everything looks fine until it is time for the store to be updated - the display is wrong - the moved item is not shown in the right place.

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 -我可以进行更多投资的时间,但我不想.选择一种不同的方法-使用传统输入并提供只读树视图.

https://bugs.dojotoolkit.org/ticket/18142 - I could invest more time in this, but I don't want to. Choosing a different approach - using traditional inputs and providing a read-only tree view.

推荐答案

在使用Observable包装外观之前,您需要将外观放置在商店的put函数周围.使用您的代码,Observable无法访问已替换的put函数.如果您仔细复制示例,它将可以正常工作

You need to place the aspect around the store's put function before wrapping it with Observable. With your code Observable hasn't got access to the replaced put function. It will work if you replicate closely the 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不支持,并且放置功能的hacking还不够).一种选择是退回到已弃用的dojo/data/ItemFileWriteStore.

UPDATE: The above solution does not support the betweenThreshold option (the ability to drop an item in between others instead of making it a child of another item). Even the official reference guide example does not work. This needs a store that properly supports positioning of items (MemoryStore doesn't and the hack for the put function is not enough). One option is to fall back on the deprecated 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 .您还可以参考此示例.

Here is another JSFiddle. You can also refer to this example.

这篇关于在Dijit树中移动节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 03:01