Hello Martin, I'm close to committing changes that will enable the propagation of value changes between trees, using something similar like qx.data.Array. In fact, I did not want to rewrite the whole TreeVirtual, using qx.data.Array, because a) I'd rather extend Derrell's excellent codebase, and b) I think that qx.data.Array doesn't scale well when you deal with a tree that has 10.000 nodes. Of course, there aren't very many use cases for trees that big, but I want to be sure not to slow the UI down. I therefore kept the native array that is the basis of Derrell's tree data model, and simulate change events whenever something changes in the tree. These changes will then be propagated to the controller and synchronized through property binding with the jsonrpc store, which, in turn, will propagate the change further to the server.
I hope to have the stuff ready by tonight and will keep you posted. Haven't thought about editable cells, but TreeVirtual somewhat different from the Table. I'll see into that. Thanks, Christian Martin Wittemann wrote: > > Hello Christian, > > the sample application looks really good. I like the fact that the > tree is filled in the background. I did also take a look at the source > code of the store and the controller. If i did get it right, you are > using a default virtaul tree model as model for the data binding? Do > you already have a plan how to handle editable cells in the tree? > You are also using native javascript arrays as container for the > nodes, right? How do you plan to handle a change in the structure of > the tree data during the runtime? > > Best, > Martin > > > Am 13.05.2009 um 21:32 schrieb panyasan: > >> >> Hello, >> >> I committed a first version of a databinding feature for >> qx.ui.treevirtual.TreeVirtual, using a jsonrpc store, in the >> contrib://qcl >> in the qcl namespace. You can have a look at the code here: >> >> https://qooxdoo-contrib.svn.sourceforge.net/svnroot/qooxdoo-contrib/trunk/qooxdoo-contrib/qcl/trunk/frontend/source/class/qcl/databinding/event/ >> >> It is currently in the qcl.databinding.event namespace, because I am >> working >> on a client-server bidirectional databinding that works with events >> that are >> sent between the client and the server. But that still needs to be >> implemented. >> >> I have created a sample application that shows how the tree works >> with huge >> datasets (up to 10.000 nodes): >> >> https://qooxdoo-contrib.svn.sourceforge.net/svnroot/qooxdoo-contrib/trunk/qooxdoo-contrib/qcl/trunk/application/databinding/ >> >> A live instance of it is here: >> >> http://m53s12.vlinux.de/cboulanger/databinding/build/ >> >> When you click on the "Get data from jsonrpc" button, you can see >> how the >> tree starts loading the first couple of nodes and then continues >> loading in >> the background. The ui stays responsive at the whole time, because the >> massive tree is divided into smaller chunks which are loaded one >> after the >> other. You can even add new nodes manually without interfering with >> the >> process. >> >> The php json-rpc backend service creates a random tree with >> 1000-9000 nodes. >> There is a small bug - sometimes the loading stops after the first >> request - >> just press the button again. >> >> The source code of the sample application is heavily documented so >> you can >> see how the API currently is designed: >> >> https://qooxdoo-contrib.svn.sourceforge.net/svnroot/qooxdoo-contrib/trunk/qooxdoo-contrib/qcl/trunk/application/databinding/source/class/databinding/Application.js >> >> Here is how the loading of the tree is implemented: >> >> /* >> * Get data from JSON-RPC backend >> */ >> var store = new qcl.databinding.event.store.JsonRpc( >> /* url */ "../services/index.php", >> /* service */ "qcl.Databinding", >> /* method */ null, >> /* marshaler */ new qcl.databinding.event.marshal.TreeVirtual >> ); >> >> var controller = new >> qcl.databinding.event.controller.TreeVirtual(null, this.treeWidget); >> store.bind("model", controller, "model"); >> [...] >> /* >> * get some local variable references for the closure >> */ >> var tree = this.treeWidget; >> var cancelButton = this.buttonCancelAddJsonRpcData; >> var startButton = this.buttonAddJsonRpcData; >> >> /* >> * clear the tree >> */ >> tree.getDataModel().clearData(); >> >> /* >> * calling getNodeCount() method on server with no >> * parameters. it returns the number of nodes on the >> * server. >> */ >> store.load("getNodeCount", [], function(data) >> { >> var nodeCount = data.nodeCount; >> >> var counter = 0; >> abortJsonRpcLoad = false; // global flag >> >> /* >> * Create a function that can recursively call itself >> * in order to load folder children, as long as there >> * are some left on the server. >> */ >> (function loadTree(data) >> { >> >> /* >> * if the function is called with boolean 'true', this >> * is interpreted as the start of the loading process. >> */ >> if (data === true) >> { >> >> /* >> * do some nice ui stuff >> */ >> tree.setAdditionalStatusBarText(" | Tree has " + >> nodeCount + " >> nodes ..."); >> cancelButton.setEnabled(true); >> startButton.setEnabled(false); >> >> /* >> * call the load method with no arguments which means >> that >> * the top level nodes are requested. >> */ >> store.load("getNodeData", [], loadTree); >> } >> >> /* >> * After the data has returned from the server, the >> function is >> * called again, and the data passed to the function. >> * We use a global flag to signal if the loading process >> should >> * be aborted. The data passed from the server has a >> 'nodes' and >> a >> * 'queue' property. The 'nodes' property will be used by >> the >> * controller to build the tree in the tree model. The >> 'queue' >> property >> * is an array of child ids which still have to be >> retrieved. If >> this >> * array is empty, we're done loading. >> */ >> else if ( ! abortJsonRpcLoad && data && typeof data == >> "object" >> && data.queue instanceof Array && >> data.queue.length ) >> { >> /* >> * display loading progress >> */ >> counter += data.nodes.length; >> var parentNodeId = data.parentNodeId; >> tree.setAdditionalStatusBarText(" | Loaded " + counter >> + " of >> " + nodeCount + " nodes..."); >> >> /* >> * now call the load method of the store with the queue >> of >> node ids that >> * still have to be retrieved. It will pull no more than >> * 10 folders (plus children) at a time to avoid >> timeouts. >> * You can play with the value of 10 to see whatever >> * works best, given the bandwith and server speed. When >> * done loading, call the loadTree function again with >> * the result. >> */ >> store.load("getNodeData", [ data.queue, 10 ], loadTree ); >> } >> >> /* >> * if no data, an error occurred >> */ >> else if (data === null) >> { >> tree.setAdditionalStatusBarText(" | *** An error occurred >> ***"); >> cancelButton.setEnabled(false); >> startButton.setEnabled(true); >> } >> >> /* >> * else, we're done. >> */ >> else >> { >> tree.setAdditionalStatusBarText(" | Finished loading " + >> nodeCount + " nodes."); >> cancelButton.setEnabled(false); >> startButton.setEnabled(true); >> } >> })(true); >> }); >> >> The data sent by the server is not converted by the json marshaler, >> because >> that would be too expensive and would actually complicate things. >> Instead, a >> special TreeVirtual marshaler converts it into a simple model with a >> few >> properties. The controller then adds data from this model to the >> TreeVirtual's own internal data model. >> >> I would be interested in feedback at this early stage, especially >> concerning >> the databinding design. >> >> Thanks, >> >> Christian >> -- >> View this message in context: >> http://www.nabble.com/Databinding-for-TreeVirtual-tp23528458p23528458.html >> Sent from the qooxdoo-devel mailing list archive at Nabble.com. >> >> >> ------------------------------------------------------------------------------ >> The NEW KODAK i700 Series Scanners deliver under ANY circumstances! >> Your >> production scanning environment may not be a perfect world - but >> thanks to >> Kodak, there's a perfect scanner to get the job done! With the NEW >> KODAK i700 >> Series Scanner you'll get full speed at 300 dpi even with all image >> processing features enabled. http://p.sf.net/sfu/kodak-com >> _______________________________________________ >> qooxdoo-devel mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel >> >> > > > ------------------------------------------------------------------------------ > The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your > production scanning environment may not be a perfect world - but thanks to > Kodak, there's a perfect scanner to get the job done! With the NEW KODAK > i700 > Series Scanner you'll get full speed at 300 dpi even with all image > processing features enabled. http://p.sf.net/sfu/kodak-com > _______________________________________________ > qooxdoo-devel mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel > > -- View this message in context: http://www.nabble.com/Databinding-for-TreeVirtual-tp23528458p23540433.html Sent from the qooxdoo-devel mailing list archive at Nabble.com. ------------------------------------------------------------------------------ The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your production scanning environment may not be a perfect world - but thanks to Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700 Series Scanner you'll get full speed at 300 dpi even with all image processing features enabled. http://p.sf.net/sfu/kodak-com _______________________________________________ qooxdoo-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
