jQWidgets Forums
jQuery UI Widgets › Forums › Grid › Equivalent to loadServerData for observablearray
This topic contains 11 replies, has 2 voices, and was last updated by andrewcb 12 years, 3 months ago.
-
Author
-
What is the best practice to dynamic load pages of data into a data adapter using data type of observablearray. I am using the data adapter with a jqxgrid with virtualmode = true and I am unable to find a way to dynamically/manually request the data from a customer web api. If I was using json, jsonp, xml, xhtml, script or text the loadServerData would fire so I could manually do the call. Is it a case of loading it as a Json object and then deserialising it into an observablearray?
Thanks
AndrewHi andrewcb,
In virtual mode, the data to be displayed should be returned in the “rendergridrows” Grid function. An example of that can be found here: virtualscrolling.htm. You may request for data in that function.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comSorry but I must be missing something.
My scenario is that I am trying to implement server side paging for 1million + records using knockout on the client and have in place editing in the gird of the knockout object.
I have an observablearray which should have a list of objects the size of the grid page. An async call gets data from the server and populates this array based on the current page of the grid whenever the page changes. A method to show/hide the grid egg timer would be useful for async operations in virtual mode.
Is the best way to implement this to capture events and render the pager based on the faux information and always let the grid render the array (length of the page) in the normal way. The rendergridrows would conflict with the actual array of items being edited supplied by the DataAdapter and don’t see how this would work as it needs a data array as the retrun result not an observablearray.
It is unclear why the dataadapter handlers only fires for certain datatypes as I would have imagined that a handler to load and pass an array of the current page of objects would have been useful for knockout and virtual grids?Thanks
AndrewHi Andrew,
The “rendergridrows” is supposed to return Array of rows. That array is what the Grid will use to display its records. It does not matter whether the Array comes from DataAdapter or not. The KO Observable array can be easily turned out into a normal JS Array
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comP.S. The issue is that the data for an observablearray can’t be requested in the rendergridrows as you can’t pass this data as observable objects back into the grid as any changes in the localdata in the adapter causes a recursive loop with the rendergridrows. Also this still doesn’t allow the grid to be bound to the knockout object (for inplace editing) as mentioned above as rendergridrows needs an array of data as return by ko.toJS, is this correct?
Found the showloadelement and hideloadelement methods
Hi
Sorry but your suggestion does not work as the data is gained through an async callback so although the data can be retrieved in the rendergridrows handler the data is not available and secondly it defeats the object, no pun intended (sorry English humour), of using ko to bind the object to UI as any updates to the knockout object will have to be performed manually. It is also very messy having an adapter as a data controller and then pushing the data in through a rendering handler.
I am still unsure why I am not able to perform this operation in the dataAdapter on the loadServerData handler and why this is only used for certain datatypes that seems to be un documented.
What I need is to trap the pager changes and manually control the page information, then call the server, on callback load the data into the observablearray in the adapater which will then update the grids data. But would love to hear a better suggestion.
Thanks
AndrewHi loadServerData.
loadServerData replaces the built-in Ajax calls of jqxDataAdapter. If you intend to load data through jqxDataAdapter and that data is not local, the loadServerData can be used and the function is called for all data types supported by jqxDataAdapter.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comSorry but that information is not correct. The function _requestData in jqx-all.js which fires the hanlder loadServerData is only called when the data adapter;
switch (datatype) {
case “json”:
case “jsonp”:
case “xml”:
case “xhtml”:
case “script”:
case “text”:
not
case “local”:
case “array”:
case “observablearray”:This is from the latest source.
Thanks
AndrewHi Andrew,
As I already wrote in the previous post “loadServerData” replaces the built-in Ajax calls of jqxDataAdapter. Ajax requests are not necessary for local data so the information is correct.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi Peter,
I think this is the core to my issue.An array or observablearray of knockout objects is just a container for data. In a virtualised grid with server side paging all the data from the server is not loaded into that local array otherwise it would defeat the point. So you need a way to Asynchronously call a server api to get additional data when the grids paging is changed, in my case, knockout objects and then load it into the local datasource used by the grid.
If an async call is done in the rendergridrows to fetch data this means the function will exit before any data is returned by the server call. Also the data required as a result for this function is an object array and not the knockout objects, so all the control data binding is lost, again defeating the point of using knockout to bind.
If the data from the ajax call is loaded into the local array as specified in the data adapter, the only way I can see to get it to use the knockout objects correctly, there is a recursive loop as the grid is rendered and rendergridrows is fired on update of the observablearray.
What I think this is pointing to is that you don’t support server side paging with knockoutjs as your original signpost to virtualscrolling.htm was to a non async loading of a plain old javascript object. I also don’t see it is best practice to trigger a async server side data request in a rendering handler as this does not allow for any Ajax (being async) as the function needs to continue execution prior to the data being received from the server.
The only obvious solution is to unbind the handler for rendergridrows before the async call is made and then rebind after the grid is refreshed, messy or a custom pager to trigger the async, but again working around your virtual implementation.
I hope you can understand what I am trying to achieve is not exotic but all code snippits I have seen do not accommodate knockout and ajax calls for server side pages of data. It seems I will need to roll my own.
Thanks
AdrewAs I had to do this without support I thought I would share.
The grid parameters are as follows:-
source: dataAdapter,
editable: true,
autoheight: true,
pageable: true,
selectionmode: ‘singlerow’,
virtualmode: true,
rendergridrows: function (params) {
return params.data;
}Trigger the data load here:-
dataAdapter.pager = function (pagenum, pagesize, oldpagenum) {
$(“#jqxgrid”).jqxGrid(‘showloadelement’);
app.dataservice.getPersons(app.peopleViewModel.people, (pagenum * pagesize) + 1, pagesize);
};Do an async call for the data page you need and then load it into the observablearray at the correct index:-
$(“#jqxgrid”).jqxGrid(‘source’).suspendKO = true;
logger.success(“queried all persons”);
peopleArray.removeAll();
var persons = data.results;
var i = start – 1;
persons.forEach(function (person) {
if (person.Selected === undefined) {
person.Selected = false;
}
peopleArray.valueWillMutate();
peopleArray()[i++] = person;
peopleArray.valueHasMutated();
});
$(“#jqxgrid”).jqxGrid(‘source’).suspendKO = false;
$(“#jqxgrid”).jqxGrid(‘updatebounddata’);
$(“#jqxgrid”).jqxGrid(‘hideloadelement’);
logger.info(“Query finished”);Quite simple really!
Thanks
Andrew -
AuthorPosts
You must be logged in to reply to this topic.