The uiProvider variable, when returned as part of a JSON object from an asynchronous value from the server, must be returned as a string value. JSON does not support literals, object names, function names, what have you, as values. http://www.json.org specifies the BNF for JSON. Right now the return value requires a literal that's used to identify the uiProvider for the nodes returned.
The problem is that none of the 3rd party JSON libraries support doing this from the server, so (referring back to the AsyncTreeNode example previously) those libraries won't, without modifying their code, return anything that's outside the JSON specification. There is a considerable difference between object notation in scripts and object notation used for data interchange. The former is very flexible, while the latter has a pretty strict set of rules applied to it. Microsoft has probably one of the better articles about this: http://msdn2.microsoft.com/en-us/library/bb299886.aspx
So, if there's a requirement to return object names from servers, we need to stick to the JSON specs for data interchange or we'll end up having to write workarounds for the majority of the server-based JSON libraries. This is actually the first time I've run into this in your library, and frankly I was surprised it wasn't in the JSON specification.
This is intended to be an attribute to a constructor call and should be a function ref. It has nothing to do with what is being loaded via XHR so I don't think it should be classified as a bug.
Every browser supports having it defined as a function ref in the JSON anyway. In fact, you can include all kinds of stuff in JSON including dates as objects (e.g. new Date(2006,12,25) ). JavaScript's interpretation of JSON is very liberal and I would suggest using that to your advantage.
However, if you can't, you can easily override createNode to eval the uiProvider.
new Ext.tree.TreeLoader({
..., // some config stuff
// inline override
createNode : function(attr){
if(typeof attr.uiProvider == 'string'){
attr.uiProvider = eval(attr.uiProvider);
}
return Ext.tree.TreeLoader.prototype.createNode.call(this , attr);
}
);
To make it easy, I have added this to the codebase for the next rev. However, I would still recommend passing the function name (non string) instead.
Hi simeon,
The workaround for JSON strings is in the TreeLoader (where we are working with JSON). It should be a function when being passed in directly. There is no equivalent on a node to map it either as we do in a TreeLoader. Problem with aspx treeloader - [SOLVED] - Tree disappears after :: uiProvider returned from JSON data must be string format - Ext JS Forums You can also set them up globally: Ext.tree.TreeLoader.prototype.uiProviders http://xn--7stq33aova165h.com/ydct/problem-with-aspx-treeloader.htmlHOME | var __trCulture={"calendar":{"calendarType":"Localized :: File Format: Unrecognized - View as HTMLLocale.parseFloat(f.value);}}},format:function(v,mask){var fmtd=vbFormat(v,mask) ;var .. (O instanceof Array)){return O}if(typeof O=="string"){return http://www.fundacion.telefonica.com/publicaciones/memorias/memoria2007/fp/shared/aspendoc-common-3.jsiHOME |
True. You'd have to do some jiggery-pokery with .split('.') to evaluate a dot notation string. Dojo has a function avoid eval and to do this! :wink:
Throws down challenge!
Snipped my post. I had a bug that was cleverly breaking my delete method.
Couldn't you use
attr.uiProvider = this.uiProviders[attr.uiProvider] ((typeof attr.uiProvider == 'string') ? window[attr.uiProvider] : attr.uiProvider);
:?:
The problem is I use the treeLoader to load the root node and all of its children but I have to replace nodes(and their children) after the user edits a node or moves a node. This is mostly due to security inheritance that cascades from a node to its children. In my use case a move can have a big impact to the ui representation. Message:: Iterator; + +import org.json.JSONObject; +import org.openrdf.model. . -45,4 + 45,8 @@ public String toString() { return value.toString() + "=" + http://simile.mit.edu/mail/ReadMsg?&msgId=22411HOME |
It seems like I should be able to use treeLoader more than once, but I couldnt' figure out how to use it to load a single node and its children after the tree has been rendered.
Regardless I have a work around. see below if anyone else has the same issue.
setUIProvider : function (node,provider) {
node.uiProvider = provider;
if (node.children)
{
for (var i=0; i < node.children.length; i++ )
{
this.setUIProvider( node.children[i] , provider);
}
}
},
So I get my new json data and call (note: HotlineNodeUI is my extention pf Ext.tree.TreeNodeUI, and dataNode is my new json data.
this.setUIProvider( dataNode, HotlineNodeUI);
This lets me walk the dataNode and apply the provider information before creating the treeNode and adding it to the tree control.
This works:
responseNodeConfig = {"text":'I confirm I have read this message', "cls":'', "allowDrag":true, "leaf":true, "allowChildren":false,"allowDrop":false, uiProvider:"PollResponseNodeUI"}
responseNodeConfig2 = {"text":'Yes she is', "cls":'', "allowDrag":true, "leaf":true, "allowChildren":false,"allowDrop":false, uiProvider:"PollResponseNodeUI"}
responseNodeConfig3 = {"text":'No she isnt', "cls":'', "allowDrag":true, "leaf":true, "allowChildren":false,"allowDrop":false, uiProvider:"PollResponseNodeUI"}
responseTree = new Ext.tree.TreePanel('ComposeEditorCenterRightBody_d iv', {
animate:true,
enableDD:true,
loader: new Ext.tree.TreeLoader({
uiProviders: {
'PollResponseNodeUI' :PollResponseNodeUI
}
}),
containerScroll: true,
ddGroup: 'pollNodeResponseDD',
lines:false,
rootVisible:false
});
root = new Ext.tree.AsyncTreeNode({
text: 'Root is hidden',
draggable:false,
id:"treeRoot",
allowDrop:true,
children: [responseNodeConfig,responseNodeConfig2,responseNod eConfig3],
type:"root"
});
But this doesn't work and probably should:
var newTreeNode = new Ext.tree.AsyncTreeNode({"text":'message', "cls":'', "allowDrag":true, "leaf":true, "allowChildren":false,"allowDrop":false, uiProvider:"PollResponseNodeUI"});
var addedNode = responseRoot.appendChild(newTreeNode);
It has the same ui error:
uiClass is not a constructor line: 16557
I can work around this by making uiProvider:PollResponseNodeUI not a string but this causes me problems since I am getting large jsons with many levels of children in the string form.
Yes, I see what you are saying. I can't get json_encode in PHP to return it in a usable fashion. I still hate the eval though (very inefficent).
So, I have added what I think will work as a flexible and efficient solution and will fall back on eval().
You can provide a hash in the config (or later):
new Ext.tree.TreeLoader({
uiProviders: {
'MyNodeUI' : MyNodeUI
}
});
You can also set them up globally:
Ext.tree.TreeLoader.prototype.uiProviders = {
....
};
Then in createNode is does a more intelligent check, avoiding the eval when it can:
if(typeof attr.uiProvider == 'string'){
attr.uiProvider = this.uiProviders[attr.uiProvider] eval(attr.uiProvider);
}
Hopefully this will solve any issues and provide some flexibility.
Animal, that won't work with namespaces. e.g. Ext.tree.TreeNodeUI would fail.
bump...
Jack, is this a bug with your uiProvider changes, or is the string uiProvider only used by treeloader or can it be used to create a singluar node?
Nortel Unveils Vision, Strategy for Israeli High-Performance Net
Busy Friday Leads to Strong Close for Net Stocks
|