Opened 9 years ago
Closed 7 years ago
#15336 closed defect (duplicate)
1.8 JsonRest+ObjectStoreModel+Tree+Observable delete a item in store, but the tree node cannot auto remove
Reported by: | jzw | Owned by: | Kris Zyp |
---|---|---|---|
Priority: | undecided | Milestone: | tbd |
Component: | Data | Version: | 1.7.2 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
hi, in "dijit/tests/tree/Tree_ObjectStoreModel.html", use dojo/store/Memory, when remove or put data, the tree can update(delete or add a node in the tree),but when use dojo/store/JsonRest instead, it not works.
below is my code and server side response data
define(["dijit/Tree", "dojo/store/JsonRest", "dijit/tree/ObjectStoreModel", "dojo/store/Observable"],function( Tree, JsonRest, ObjectStoreModel, Observable){ jsonRest = new JsonRest({ target:"/items/", getChildren: function(object){ return this.query(object.id); } }); jsonRest = Observable(jsonRest); var treeModel = new ObjectStoreModel({ store: jsonRest, query:"root", mayHaveChildren: function(item){ return item.children==true; } }); tree = new Tree({ model : treeModel, persist:false },"treeDiv"); tree.startup(); function removeSelectedNode(){ var selectItem = tree.get("selectedItem"); jsonRest.remove(selectItem.id); } });
server side response data.
target:data/root
[ {id:1,name:'n1',children:true, parent:'root'}, {id:2,name:'n2',children:true, parent:'root'} ]
but when i select a node and execute removeSelectedNode() function, in server side ,the data is delete success,but in browser the node is still there quietly and smile at me( :( ).
Did I miss something, or it's a bug? thanks
Change History (8)
comment:1 Changed 9 years ago by
Component: | General → Data |
---|---|
Owner: | set to Kris Zyp |
comment:2 Changed 9 years ago by
trace the code, found "children.observe" is undefined in dijit/tree/ObjectStoreModel。
line 246
if(children.observe){ //code }
and in dojox/store/Observable line 67 resultsArray.length always = 0 so the follow code never runs
// remove the old one for(i = 0, l = resultsArray.length; i < l; i++){ var object = resultsArray[i]; if(store.getIdentity(object) == existingId){ removedObject = object; removedFrom = i; if(queryExecutor || !changed){ resultsArray.splice(i, 1); } break; } }
isn't it?
comment:3 Changed 9 years ago by
Hi,
I've been playing around with objectStoreModel in 1.8.0b1 and ran into a similar problem. I think I know what's causing this.
The objectStoreModel assumes the result of this.store.getChildren() is an array, however if your working with a jsonRest the result will be a queryResult.
This how I resolved the issue:
from line 129 in getChildren
Code highlighting:
// Setup listener in case children list changes, or the item(s) in the children list are // updated in some way. // FIX: replace children with this.childrenCache[id] if(this.childrenCache[id].observe){ // FIX: replace children wirh this.childrenCache[id] this.childrenCache[id].observe(lang.hitch(this, function(obj, removedFrom, insertedInto){ console.log("observe on children of ", id, ": ", obj, removedFrom, insertedInto); ... ))}
and in pasteItem
Code highlighting:
if(!bCopy){ var queryResult = this.childrenCache[this.getIdentity(oldParentItem)]; Deferred.when(queryResult, lang.hitch(this, function(oldParentChildren){ index = array.indexOf(oldParentChildren, childItem); oldParentChildren.splice(index, 1); this.onChildrenChange(oldParentItem, oldParentChildren); })); }
Hope this helps.
comment:4 Changed 7 years ago by
Looks like this is still an issue with 1.9. getChildren seems to work, but pasteItem - when using drag and drop plus JsonRest?, doesn't work. The code cjong used didn't work for me when moving the node within the same parentItem. Change I did allows sorting between the same parentItem, but there still is an issue with moving nodes around. When you move a node outside a parentItem, it is never added to the newParentItem. However if you move a node inside a parent (could be nested), it will work. If I can get that to work I will post some newer code.
if (!bCopy) { if (oldParentItem === newParentItem) { var res = this.childrenCache[this.getIdentity(oldParentItem)]; when(res, lang.hitch(this, function (oldParentChildren) { var old_index = array.indexOf(oldParentChildren, childItem); var new_index = insertIndex; if (new_index >= oldParentChildren.length) { var k = new_index - oldParentChildren.length; while ((k--) + 1) { oldParentChildren.push(undefined); } } oldParentChildren.splice(new_index, 0, oldParentChildren.splice(old_index, 1)[0]); this.onChildrenChange(oldParentItem, oldParentChildren); })); } else { var res = this.childrenCache[this.getIdentity(oldParentItem)]; when(res, lang.hitch(this, function(oldParentChildren){ var index = array.indexOf(oldParentChildren, childItem); oldParentChildren.splice(index, 1); this.onChildrenChange(oldParentItem, oldParentChildren); })); } }
comment:5 Changed 7 years ago by
Okay, here is a better version that for the most part fixes everything for 1.9.
What's Still broken:
- The icons do not change they now have children or no children
- If you drag and drop multiple items at the same time, the last item (if it is greater than two items) is never moved. There is an error happening saying it has no parent...
if (!bCopy) { oldParentId = this.getIdentity(oldParentItem); newParentId = this.getIdentity(newParentItem); oldParentChildrenCache = this.childrenCache[oldParentId]; newParentChildrenCache = this.childrenCache[newParentId]; when(oldParentChildrenCache, lang.hitch(this, function (oldParentChildren) { if (oldParentItem === newParentItem) { //-- This is the same parent var lastIndex = array.indexOf(oldParentChildren, childItem); oldParentChildren.splice(insertIndex, 0, oldParentChildren.splice(lastIndex, 1)[0]); } else { var index = array.indexOf(oldParentChildren, childItem); oldParentChildren.splice(index, 1); } this.onChildrenChange(oldParentItem, oldParentChildren); if (oldParentItem !== newParentItem) { //-- Add in the newer copy when(newParentChildrenCache, lang.hitch(this, function(newParentChildren) { childItem.parent = newParentItem.id; if (newParentChildren == null) { newParentChildren = []; } newParentChildren.splice(insertIndex, 0, childItem); this.onChildrenChange(newParentItem, newParentChildren); })); } })); }
I also found that if you place an item, below a folder, the folder expands. dijit/tree/dndSource.js -> onDndDrop
So I made this change to that file:
onDndDrop: function(source, nodes, copy){ var expandOver = false; if(this.containerState == "Over"){ ... if(this.dropPosition == "Before" || this.dropPosition == "After"){ ... }else{ ... expandOver = true; } ... if (expandOver) { this.tree._expandNode(target); } } this.onDndCancel(); },
comment:6 Changed 7 years ago by
Disappointed to see this issue is still not fixed. We're in 1.9.3 now and I still don't see an update of the tree after putting a new child.
comment:7 Changed 7 years ago by
I have almost same problem. I have tree connected with jsonrest store wrapped in Observable. When I query, I get new data, but Tree won't refresh. Going to write new bug report, mb some1 will get look at it ;-)
My guess is that Observable is not giving a notification that the item was deleted.