我有一个由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);
}
}
如果传递的父项为空并且TreeStoreModel
和onLeaveRoot
事件未在onAddToRoot
中传递,则insertIndex
不会更新基础数据存储,所以我不能使用它们来更新我的数据存储(无论如何它似乎有点倒退)。
此时我认为唯一可行的选择是扩展ForestStoreModel
以便允许我将合成$root$
项设置为兼容的数据存储对象并允许ForestStoreModel
不加改变地传递给TreeStoreModel
。
还有其他方法可以解决这个问题吗?
更新
最终的解决方案比建议的更简单。我的ForestStoreModel
已经是一个自定义类,因为我实际上使用dojo 1.6 ObjectStore作为数据源,所以我可以将options
参数中的所需索引传递给对象库put
方法。修复只是一个单行,因为我让父类负责调用onLeaveRoot
和onAddRoot
:
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);
}
答案 0 :(得分: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);
}
}
});