Hey guys,
I am unable to get LoadOnDemand working properly for the igTree. I'm sure it's just that I'm calling it incorrectly, sor maybe my data format is being returned incorrectly from the server. Here are some things that I have tried:
1. When I set the DataSourceUrl property (and leave DataSource blank), my service code gets called, but no nodes render on the tree.
function loadTreeByUrl() { var treeServiceString = "http://localhost/igTreePOC/Services/treeService?$format=json&$callback=?";
//var json = new $.ig.JSONDataSource({ dataSource: treeServiceString, responseDataKey: "d" });
$("#treeTargetU").igTree({ dataSourceUrl: treeServiceString, //dataSource: json, dataSourceType: "json", responseDataKey: "d", responseDataType: "json", initialExpandDepth: 1, loadOnDemand: true, width: 500, bindings: { textKey: 'DisplayString', valueKey: 'TreeNodeString', primaryKey: 'TreeNodeString', childDataProperty: 'TreeNodeList', bindings: { textKey: 'DisplayString', valueKey: 'TreeNodeString', primaryKey: 'TreeNodeString', childDataProperty: 'TreeNodeList' } } });}
2. When I set the DataSource property (and leave the DataSourceUrl blank), my service code gets called, the root level nodes get rendered, but when trying to expand any of the root-level nodes, I get the following error, and my service code does NOT get called:
JavaScript runtime error: The igTree control requires a dataSourceUrl provided in order to initiate a request for data to that URL.
function loadTreeByDataSource() { var treeServiceString = "http://localhost/igTreePOC/Services/treeService?$format=json&$callback=?";
var json = new $.ig.JSONDataSource({ dataSource: treeServiceString, responseDataKey: "d" });
$("#treeTargetD").igTree({ //dataSourceUrl: treeServiceString, dataSource: json, dataSourceType: "json", //responseDataKey: "d", responseDataType: "json", initialExpandDepth: 1, loadOnDemand: true, width: 500, bindings: { textKey: 'DisplayString', valueKey: 'TreeNodeString', primaryKey: 'TreeNodeString', childDataProperty: 'TreeNodeList', bindings: { textKey: 'DisplayString', valueKey: 'TreeNodeString', primaryKey: 'TreeNodeString', childDataProperty: 'TreeNodeList' } } });}
3. When I set the DataSourceUrl AND DataSource properties, my service code gets called, the root level gets populated corrrectly, and my service code gets called when I try to expand one of the root nodes. However, when the call comes back, no child nodes get populated.
function loadTreeByBoth() { var treeServiceString = "http://localhost/igTreePOC/Services/treeService?$format=json&$callback=?";
$("#treeTargetBoth").igTree({ dataSourceUrl: treeServiceString, dataSource: json, dataSourceType: "json", responseDataKey: "d", responseDataType: "json", initialExpandDepth: 1, loadOnDemand: true, width: 500, bindings: { textKey: 'DisplayString', valueKey: 'TreeNodeString', primaryKey: 'TreeNodeString', childDataProperty: 'TreeNodeList', bindings: { textKey: 'DisplayString', valueKey: 'TreeNodeString', primaryKey: 'TreeNodeString', childDataProperty: 'TreeNodeList' } } });}
The JSON strings that I am passing back from the server are:
private const string RESULTS_ROOT = "{\"d\":[{\"DisplayString\":\"Wheat\",\"TreeNodeString\":\"3?1001-0=\",\"TreeNodeList\":[]},{\"DisplayString\":\"Barley\",\"TreeNodeString\":\"3?1002-0=\",\"TreeNodeList\":[]},{\"DisplayString\":\"Beans\",\"TreeNodeString\":\"3?1003-0=\",\"TreeNodeList\":[]}]}"; private const string RESULTS_WHEAT = "{\"d\":[{\"DisplayString\":\"Wheat-CPSR\",\"TreeNodeString\":\"3?1001-0=9\",\"TreeNodeList\":[]},{\"DisplayString\":\"Wheat-CWAD\",\"TreeNodeString\":\"3?1001-0=4\",\"TreeNodeList\":[]},{\"DisplayString\":\"Wheat-CWES\",\"TreeNodeString\":\"3?1001-0=7\",\"TreeNodeList\":[]},{\"DisplayString\":\"Wheat-CWGP\",\"TreeNodeString\":\"3?1001-0=8\",\"TreeNodeList\":[]},{\"DisplayString\":\"Wheat-CWHWS\",\"TreeNodeString\":\"3?1001-0=3\",\"TreeNodeList\":[]},{\"DisplayString\":\"Wheat-CWRS\",\"TreeNodeString\":\"3?1001-0=2\",\"TreeNodeList\":[]},{\"DisplayString\":\"Wheat-CWRW\",\"TreeNodeString\":\"3?1001-0=5\",\"TreeNodeList\":[]},{\"DisplayString\":\"Wheat-CWSWS\",\"TreeNodeString\":\"3?1001-0=6\",\"TreeNodeList\":[]}]}"; private const string RESULTS_BARLEY = "{\"d\":[{\"DisplayString\":\"Barley-Feed CW Hulled\",\"TreeNodeString\":\"3?1002-0=70\",\"TreeNodeList\":[]},{\"DisplayString\":\"Barley-Feed CW Hulless\",\"TreeNodeString\":\"3?1002-0=71\",\"TreeNodeList\":[]},{\"DisplayString\":\"Barley-Food CW Hulled\",\"TreeNodeString\":\"3?1002-0=12\",\"TreeNodeList\":[]},{\"DisplayString\":\"Barley-Food CW Hulless\",\"TreeNodeString\":\"3?1002-0=13\",\"TreeNodeList\":[]}]}"; private const string RESULTS_BEANS = "{\"d\":[{\"DisplayString\":\"Beans-Black\",\"TreeNodeString\":\"3?1003-0=17\",\"TreeNodeList\":[]},{\"DisplayString\":\"Beans-Great Northern\",\"TreeNodeString\":\"3?1003-0=19\",\"TreeNodeList\":[]},{\"DisplayString\":\"Beans-Navy\",\"TreeNodeString\":\"3?1003-0=18\",\"TreeNodeList\":[]},{\"DisplayString\":\"Beans-Pinto\",\"TreeNodeString\":\"3?1003-0=16\",\"TreeNodeList\":[]},{\"DisplayString\":\"Beans-Shiny Black\",\"TreeNodeString\":\"3?1003-0=21\",\"TreeNodeList\":[]},{\"DisplayString\":\"Beans-Small Red\",\"TreeNodeString\":\"3?1003-0=20\",\"TreeNodeList\":[]},{\"DisplayString\":\"Beans-Yellow\",\"TreeNodeString\":\"3?1003-0=22\",\"TreeNodeList\":[]}]}";
I have attached a sample project, that attempts to bind 3 different trees using each of the methods described above. It's using a fresh download (from Sep 15, 2015) of the igniteUI 2015.1 toolset. (My target code base is on 2014.2, and I get the same problem there too, but if we can only get it running on 2015.1, I'm willing to upgrade.) Also, I do have quite a bit of control over how the JSON strings get rendered to the client, so if the problem is the format of the JSON, I can work with that too. Unfortunately, the project isn't an MVC project, so I don't know if I'd be able to implement an MVC solution.
If anyone has any ideas, they'd be greatly appreciated!
Thanks!
Jamie Foster
I DO need to use load-on-demand for this tree. The nodes are generated dynamically, there are potentially tens of thousands of them, and unknown number of levels deep, and the sql to generate them can be quite slow.
Hey Damyan,
Your solution works perfectly! I just had to use your javascript (and especially the url format!), and was able to leave my server-side as-is.
Thank you so much for your help!!
Jamie
Hello Jamie,
I’m not sure how this sample project relates to your actual project usage, but I do still have a few notes:
- Load on demand does require the DataSourceUrl to be set (otherwise the tree wouldn’t know where to look for child data) so the error message in the second case is correct.
- Because the tree supports different ways to request data, some of those are sensitive to the type of data and the actual URL itself. The “$callback” in the URL is an indication to set both the data source and jQuery requests in JSONP mode, which causes the parsing of the result to fail as the data in not wrapped in the callback call.
- The third option you tried is hybrid solution where the tree would render the local data and try to merge it with the remote (which fails like above) so you still get just the local source and essentially no load on demand.
So, solutions – there are probably more than a few, but quickest way is to remove the “$callback” part of the url so the data with DataSourceUrl will load correctly. Also url it sort of looks like oData, but at least here it’s not on the backend and neither is the json data in the supported format, so you should also remove the object wrap (d) from the json as normal load on demand doesn’t expect those for child requests usually handled by the MVC model. So something like:
private const string RESULTS_ROOT = "[{\"DisplayString\":\"Wheat\", … ]";
private const string RESULTS_WHEAT = "[{\"DisplayString\":\"Wheat-CPSR\", … ]";
function loadTreeByUrl() {
var treeServiceString = "http://localhost/igTreePOC/Services/treeService?$format=json";
$("#treeTargetU").igTree({
dataSourceUrl: treeServiceString,
responseDataType: "json",
initialExpandDepth: 1,
loadOnDemand: true,
width: 500,
bindings: {
textKey: 'DisplayString',
valueKey: 'TreeNodeString',
primaryKey: 'TreeNodeString',
childDataProperty: 'TreeNodeList',
childDataProperty: 'TreeNodeList'
}
});
I’m not sure what type of project you are using, but you might be able to bring in the MVC assembly into ASP.NET WebForms project (newer projects usually mix easily anyway) and be able to just use the tree model to parse the query and load the data for you.
There are options to use events to alter the default behaviors or even add completely custom implementation of loading child data as a last resort, but for now let me know if something like this works for you.
Regards,
Damyan Petev
Associate Software Developer
Infragistics, Inc.
I have investigated your case, but I wasn’t able to find what is causing the issue. I have modified your treeNavigator.js file to use mockjs and I was able to load the nodes. I’m sending you the file just for you to take a look at it. I will further investigate the case and I’ll follow up with you regarding my findings.
Thank you for using our community.
I’m investigating your case. Meanwhile here are some links that can help you better understand the igTree control.
http://ko.infragistics.com/community/blogs/craig_shoemaker/archive/2013/03/27/remote-load-on-demand-with-the-ignite-ui-igtree.aspx
http://www.igniteui.com/help/igtree-optimize-performance#enable-load-on-demand