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
