【问题标题】:How to arrange top-level node items in a dijit Tree via drag and drop如何通过拖放在 dijit 树中排列顶级节点项
【发布时间】:2011-08-03 20:01:26
【问题描述】:

我有一个 dijit.Tree 支持一个 ForestStoreModel,它使用自定义数据存储来提供数据。它工作得很好,但我想为用户提供通过 dojo 拖放功能重新排列顶级项目(并且只有顶级)项目的能力。

问题在于ForestStoreModel::pasteItem 函数检查项目是否是根的子项,然后将null 传递给TreeStoreModel::pasteItem

pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy, /*int?*/ insertIndex){
        // summary:
        //      Move or copy an item from one parent item to another.
        //      Used in drag & drop
        if(oldParentItem === this.root){
            if(!bCopy){
                // It's onLeaveRoot()'s responsibility to modify the item so it no longer matches
                // this.query... thus triggering an onChildrenChange() event to notify the Tree
                // that this element is no longer a child of the root node
                this.onLeaveRoot(childItem);
            }
        }
        dijit.tree.TreeStoreModel.prototype.pasteItem.call(this, childItem,
            oldParentItem === this.root ? null : oldParentItem,
            newParentItem === this.root ? null : newParentItem,
            bCopy,
            insertIndex
        );
        if(newParentItem === this.root){
            // It's onAddToRoot()'s responsibility to modify the item so it matches
            // this.query... thus triggering an onChildrenChange() event to notify the Tree
            // that this element is now a child of the root node
            this.onAddToRoot(childItem);
        }
    }

如果传递的父项为空并且onLeaveRootonAddToRoot 事件未传入insertIndex,则TreeStoreModel 不会更新基础数据存储,因此我无法使用它们来更新我的数据存储(无论如何,这似乎有点倒退)。

在这一点上,我认为唯一可行的选择是扩展 ForestStoreModel 以允许我将合成的 $root$ 项目设置为兼容的数据存储对象并允许 ForestStoreModel 传递它,不变,到TreeStoreModel

还有其他方法可以解决这个问题吗?

更新

最终的解决方案比建议的还要简单。我的ForestStoreModel 已经是一个自定义类,因为我实际上使用dojo 1.6 ObjectStore 作为数据源,所以我可以将options 参数中所需的索引传递给对象存储put 方法。修复只是一条线,因为我让父类负责调用 onLeaveRootonAddRoot

pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy, /*int?*/ insertIndex){
    // Handle drag & drop at the root level
    if (oldParentItem === this.root && newParentItem === this.root){
        this.store.put(childItem, { index: insertIndex });
    } 
    this.inherited(arguments);
}

【问题讨论】:

  • 那个更新应该是一个答案。

标签: drag-and-drop tree dojo


【解决方案1】:

你需要继承ForestTreeModel,你无法逃避它。但是,您只需要覆盖pasteItem。您不能将合成根传递给TreeStoreModel,因为它对此一无所知。

如果需要修改底层数据存储,最好直接调用this.store.setValues()。这应该会触发onSetItem 事件,然后为您调用_requeryTop(),这将按照您排列它们的任何顺序从底层存储中获取根,因此请务必在您的修改中反映这一点。

dojo.declare('MyForestTreeModel', [ dijit.tree.ForestTreeModel ], {
  pasteItem: function(childItem, oldParentItem, newParentItem, bCopy, insertIndex) {
    if (oldParentItem == this.root && newParentItem == this.root) {
      if (!bCopy) { this.onLeaveRoot(childItem); }
      // modify the underlying store somehow so the call to _requeryTop() fetches
      // the items in the correct order.
      // (you decide what's 'order' and what new_order() returns)
      this.store.setValues(childItem, 'order', new_order(insertIndex));
      this.onAddRoot(childItem);
    } else {
      // call super
      this.inherited(arguments);
    }
  }
});

另一种更简单的方法是自己操作this.root.children,然后发出事件onChildrenChange 来通知视图。请注意,该方法不会保留订单。

dojo.declare('MyForestTreeModel', [ dijit.tree.ForestTreeModel ], {
  pasteItem: function(childItem, oldParentItem, newParentItem, bCopy, insertIndex) {
    if (oldParentItem == this.root && newParentItem == this.root) {
      if (!bCopy) { this.onLeaveRoot(childItem); }
      // manipulate this.root.children to reorder childItem
      // remove child from the current position
      var children = dojo.filter(this.root.children, function(x) {
        return x != childItem;
      });
      // and insert it into the new index
      children.splice(insertIndex, 0, childItem);
      this.root.children = children;
      // notify views
      this.onChildrenChanged(this.root, children);
      this.onAddRoot(childItem);
    } else {
      // call super
      this.inherited(arguments);
    }
  }
});

【讨论】:

  • 我确实需要修改数据存储,所以我会根据您的第一个建议尝试一个版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 2018-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多