My goal is simply to generate a viewModel via Knockout.Mapping, bind a igGrid to the viewModel, and then refresh the viewModel and grid via an ajax call to a controller that returns JSON. I am using VisualStudio 2013 and MVC 5. I have the correct libraries referenced. I am able to get the Infragistics Knockout Integration sample to work correctly, but in the sample there are a lot of hard coded references to column names. I don't want to reference the column names directly, but rather rely on knockout mapping to create my observable viewModel. The initial model binding works fine, and the populated grid is correctly displayed. When I attempt to refresh the grid after the Ajax call, the browser freezes and I have to terminate IE. Can someone show me a simple example of how this can be accomplished?
HTML - <table id="grid" data-bind="igGrid: { dataSource: myData, primaryKey: 'ID', features: [{ name: 'Updating', editMode: 'none', enableAddRow: false, enableDeleteRow: true, columnSettings: [ ] }] }"></table>
JavaScript -
$(document).ready(function () {
var model = @Html.Raw(Json.Encode(Model))
viewmodel = ko.mapping.fromJS(model)
ko.applyBindings(viewmodel); };
function getRefreshedModel()
{
$.ajax({
url:"/Controller/Action/",
type:'post',
data: dataString,
contentType:'application/json',
success: function (results) { ko.mapping.fromJS(results, viewmodel); } //refresh the model and grid
});
}
Hello,
When you try to reload your view model with a new set of data, the grid will try to find the differences between the two and apply them without re-rendering itself. This is one of the key features of the grid's Knockout integration, however it can be slow with very big chunks of data, which might be what's causing this freezing. What is the amount of records the server sends in your case? Could you please share which version of Ignite UI you are using?
I am looking forward to hearing from you!
Best regards,
Stamen Stoychev
Hi,
I don't think it is a recordsize issue because I am only returning about 100 results. Is it possible to do without hand coding the view model and just using mapping plug in? The example Infragistics provides is mapped by hand.
I believe that I am using the latest version of igniteUI, which is in the download is a subfolder within the Infragistics/2013.2 folder. Incidently I have found that Infragistics needs to abandon the mapping plugin and go with a rewrite that is called viewModel. In my testing it is 100 times faster on data load.
I attempted to implement paging in the grid, but when I click on the "next" button, I get a JavaScript error. It seems that this may be related to the binding problem as the grid attempts to bind to the next group of data.
Error Msg - "JavaScript runtime error: Unable to get property 'dataType' of undefined or null reference"
Occurs in Function - "function applyBindingsToNodeInternal(node, sourceBindings, bindingContext, bindingContextMayDifferFromDomParentElement)" during this section - "// Run init, ignoring any dependencies"
I am just checking if the latest reply helped you out and if you require any further assistance on the matter.
Hi, thank you for checking back, Dimi. I have been on vacation in South America (returning Jan 15th to the US), so it is taking me a while to get back to your last communication. I don't have any configuration differences that I am aware of that would affect the ability to implement paging. It is possible that I have a JavaScript library conflict, so I will try a stripped down example next.
I'm just checking if you still need assistance with this case.
I have yet to nail down why I am getting an error when attempting to page the grid. The grid loads fine initially and has the correct row count.
<script>
// define vars used for the data model at the script level so that they are accessible across functions var model, datasource
// configure policy igGrid
var gridOpts = {
primaryKey: 'PolicyCoverageID',
autoGenerateColumns: false,
width: "100%",
columns: [
{ headerText: "Coverage", key: "Coverage", dataType: "string", width: "5%" },
{ headerText: "From Date", key: "FromDate", dataType: "string", width: "10%" },
{ headerText: "To Date", key: "ToDate", dataType: "string", width: "10%" },
{ headerText: "RetroDate", key: "RetroDate", dataType: "string", width: "10%" },
{ headerText: "Class", key: "Class", dataType: "string", width: "5%" },
{ headerText: "Specialty", key: "Specialty", dataType: "string", width: "10%" },
{ headerText: "PolicyNumber", key: "PolicyNumber", dataType: "string", width: "10%" },
{ headerText: "Limit", key: "Limit", dataType: "string", width: "10%" },
{ headerText: "Status", key: "Status", dataType: "string", width: "5%" },
],
features: [
name: "Resizing"
},
name: 'Paging',
type: 'local',
pageSize: 5
]
};
// Convert the model returned from the controller to a JSON object
datasource = @Html.Raw(Json.Encode(Model))
// Map the JSON object fields
model = ko.mapping.fromJS(datasource);
// Set policy igGrid datasource
gridOpts.dataSource = model.Policies;
// Bind to all JSON object fields
ko.applyBindings(model);
// Drop the igGrid bindings (bug?)
ko.cleanNode($("#policyGrid")[0]);
// Rebind the policy igGrid
ko.applyBindingsToNode($("#policyGrid")[0], { igGrid: gridOpts }, model);
function getAccount()
// Define the data that will be posted to the Controller method
var dataString = "{ 'PolicyHolderAccountNo': \"" + $('#PolicyHolderAccountNo').val() + "\"}";
// Post to the Controller method via Ajax
url: "/Inquiry/GetPolicy/",
type: 'post',
contentType: 'application/json',
beforeSend: function () { spinner = new Spinner(opts).spin(document.getElementById('loadingSpinner')); },
complete: function () { $('#PolicyHolderAccountNo').val(''); spinner.stop(); },
success: function (result) {
// Drop the igGrid binding due to problem with refresh
// Refresh the model
ko.mapping.fromJS(result, model);
// Reapply the bindings directly to the igGrid
ko.applyBindingsToNode($("#policyGrid"), { igGrid: gridOpts }, model);
error: function (jqXHR, textStatus, errorThrown) {
var errorMessage = '';
$('#message').html(jqXHR.responseText);
</script>
I created a support ticket on your behalf with number CAS-128503-X2Y9B9. Log in our website and go to Account - Support Activity and there you will see your ticket under Active cases. I will contact you through this case with instructions on how to send the sample.
Nikolay,
I fixed the paging issue, but I still have an issue wherein populating the grid with a JSON response works the first time, but not on the second attempt.
I put together a sample wherein you can enter a 6 digit number in a searchbox which will call a post method in the controller. This works correctly the first time and populates the grid. If you attempt it a second time, then you will get an error. I am certain that the problem is somewhere in the JavaScript as I have debugged and the second response from the server is exactly the same as the working first response(JSON result). It's as if a value is out of scope during the second call to exports.fromJS. If there is a better way (best practice) for binding the data to the grid, then this problem might go away.
The sample is 41mb zipped which is being rejected by the ticket attachment. Do you have an ftp or email I can send it to?
Thank you for sharing your code.
It seems correct and I am so far unable to determine what may be causing this error. I would be very helpful if you could provide a running sample, reproducing the issue, so I can debug it on my side.