PDA

View Full Version : Tree & update on a record (with full sample)



Araberen
22 Dec 2011, 12:56 AM
Hi,

Simple use case:
A tree with a REST proxy. When I drag/drop an element on that tree (there is just one tree!), I want to update the database, so I run a save on the given record.

Here is a full example: http://fabienrenaud.com/extjs/tree.html
Try to drop Node 11 into Node 3 and see the problem:
30228

Here are the sources: http://fabienrenaud.com/extjs/tree.zip (html/js + php)

More precisely...


tree.getView().on('drop', function(node, data, overModel, dropPosition, eOpts) {
var record = data.records[0];

// If I do not run that method, the layout will be fine.
// But I have to and the layout is not ok anymore.
// This is because of the response of the PUT request...
record.save();
});

The response of the PUT request is something like:

{"success":true,"data":[{"id":5,"title":"Node 11"}]}
The problem comes from the 'data' value.
If I leave it blank or if I do not declare that field, the tree's layout will be ok. but an exception will be raised: 'Uncaught TypeError: Cannot read property 'data' of undefined'... and the tree will bug soon after a couple of more actions...

Any idea?

mitchellsimoens
22 Dec 2011, 11:33 AM
When you are saving a single model using the model's save method, you shouldn't return an array. Have you tried using the sync method on the treestore.

Araberen
22 Dec 2011, 1:01 PM
When you are saving a single model using the model's save method, you shouldn't return an array.
That's not the idea I had when programming with REST. POST have to return the object, especially to get the new id. So PUT should do the same (because some fields could be updated just on the server).
And other topics (http://stackoverflow.com/questions/2065664/in-rest-should-i-return-the-representation-in-response-to-a-put) confirm that opinion.

...
Finally the sync methods works but I had to rewrite the buildUrl of my store's proxy.
... because...

About REST:
/rest/treeitem/1 should return informations just about the tree item with id 1
So, when I make the model for a treeitem, I write its proxy like this:


proxy : { type:'rest', url:'/rest/treeitem' } // This perfectly match the model

Then I make a treestore using that model. But it doesn't get the children of the tree items because /rest/treeitem doesn't give that information. So I have to call /rest/treeitem/children/<id> to get the children of the treeitem with id <id>. So I add a proxy to the treestore to overwrite the model's proxy:

proxy: { type:'rest', url:'rest/treeitem/children' } // which will be used to get children of tree items
But now, I totally lose the consistency of REST. Because calling sync on the treestore proxy to update a treeitem will call /rest/treeitem/children !!!

...
In my opinion, this is an inconsistency of the ExtJS treestore which should automatically add the 'children' text when calling children through the REST proxy of the model (and not the store)... because REST is hypertext driven!
So, I totally rewrite the buildUrl of my treestore's proxy:


buildUrl: function(request) {
var me = this,
proxy = me.getTree().getStore().getProxy(),
operation = request.operation,
url = proxy.getUrl(request);

if (!url.match(/\/$/)) {
url += '/';
}
switch (operation.action) {
case "read":
if (operation.params) {
if (operation.params.id) {
url += "children/" + operation.params.id;
operation.params = [];
}
}
break;
case "update":
if (operation.records.length == 1) {
url += operation.records[0].internalId;
}
break;
}

return url;
}

And that is my best solution til now. It works perfectly fine like that.