All of our CRUD via inline grid / popups are being are being followed by a full read of the datasource to keep things in synch (please see sample transport code).
I know this full refresh of the datasource is not necessary. I am trying to understand what is required :
1) Following a successful deletion do I need to delete a row from the grid and datasource and how?
2) Following a successful update do I need to set reset dirty flags to false? Anything else?
3) Following a successful insert how do return extract new key id value and use to synch grid and datasource ?
transport:
{
read: function (options) {
$.ajax({
url: siteUrlRel + "/Handlers/GenericHandler.aspx?sp=sp_getAddresses",
dataType: "json",
type: "GET",
cache: false,
contentType: "application/json; charset=utf-8",
success: function (result) {
options.success(result);
}
});
},
create: function (options) {
$.ajax({
url: siteUrlRel + "/Handlers/GenericCRUDHandler.aspx?sp=sp_addAddress",
data: encodePlus(kendo.stringify(options.data)),
dataType: "json",
async: false,
type: "POST",
success: function (response) {
addressesDataSource.read();
},
error: function (response) {
alert(response);
addressesDataSource.cancelChanges();
}
});
},
update: function (options) {
$.ajax({
url: siteUrlRel + "/Handlers/GenericCRUDHandler.aspx?sp=sp_updateAddress",
data: encodePlus(kendo.stringify(options.data)),
async: false,
dataType: "json",
type: "POST",
success: function (response) {
addressesDataSource.read();
UpdateMessage("Addresses changes applied");
}
});
},
destroy: function (options) {
$.ajax({
url: siteUrlRel + "/Handlers/GenericCRUDHandler.aspx?sp=sp_deladdresses",
data:encodePlus(kendo.stringify(options.data)),
async: false,
type: "POST",
success: function (response) {
addressesDataSource.read();
},
error: function (response) {
alert(response.responseText);
addressesDataSource.cancelChanges();
}
});
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
11 Answers, 1 is accepted
Regarding the read method which is call on every create, update and delete- this is not necessary as the Grid will be updated automatically, this includes the data and the UI. In fact, this is making unnecessary calls to the remote server and can cause performance issues.
Regarding the three question: These will be made automatically by the Grid if the remote service is implemented correctly.
I can suggest checking the information for the CRUD data operations:
http://docs.telerik.com/kendo-ui/framework/datasource/crud
Also, check our demo examples for the editable Grid:
http://demos.telerik.com/kendo-ui/grid/editing-inline
I hope this is helpful.
Regards,
Stefan
Telerik by Progress
Hi Stefan,
I know for the create, update and delete operations to work automatically the remote service needs to return data the same as expected by the read. In our case we do not return data like this. We either return an error message (if there is any) or new id (in the case of a create). I need our remote database access code to remain like this otherwise it will mean major changes.
Please can you provide examples how I can manually deal with create, update and delete operations in our case.
regards,
Gary
If the data format is different than the expected one, I can suggest using the schema.parse property of the DataSource to preprocess the data from the server and parse it on the client, and the parameterMap property to modify the result from the client before sending it to the server:
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-schema.parse
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.parameterMap
If you still need to implement custom CRUD operations and our assistance is needed, please send an example so we can offer a suggestion best suited for it.
Regards,
Stefan
Telerik by Progress
Stefan,
I have given you a revised code example from the one at the at the start of this post. It includes the data model. I am not sure what else I can provide you with that would help.
At the moment the response from CRUD operations is a database error message if any is raised otherwise on response we don't send back any other data. We should be able to easily to change this to send back the id value (in the example address_id) of the record involved (which would be essential for an create operation but not sure it would be necessary for and update or destroy?). This would allow to complete the sychronisation on the client side. I am assuming we need some alternative some code in the success functions for create, update and destroy?
If you could provide some generic pseudo code how to handle this that would be great.
var
addressesDataSource =
new
kendo.data.DataSource(
{
transport:
{
read:
function
(options) {
$.ajax({
url: siteUrlRel +
"/Handlers/GenericHandler.aspx?sp=sp_getAddresses"
,
dataType:
"json"
,
type:
"GET"
,
cache:
false
,
contentType:
"application/json; charset=utf-8"
,
success:
function
(result) {
options.success(result);
}
});
},
create:
function
(options) {
$.ajax({
url: siteUrlRel +
"/Handlers/GenericCRUDHandler.aspx?sp=sp_addAddress"
,
data: encodePlus(kendo.stringify(options.data)),
dataType:
"json"
,
async:
false
,
type:
"POST"
,
success:
function
(response) {
addressesDataSource.read();
},
error:
function
(response) {
alert(response);
addressesDataSource.cancelChanges();
}
});
},
update:
function
(options) {
$.ajax({
url: siteUrlRel +
"/Handlers/GenericCRUDHandler.aspx?sp=sp_updateAddress"
,
data: encodePlus(kendo.stringify(options.data)),
async:
false
,
dataType:
"json"
,
type:
"POST"
,
success:
function
(response) {
addressesDataSource.read();
UpdateMessage(
"Addresses changes applied"
);
}
});
},
destroy:
function
(options) {
$.ajax({
url: siteUrlRel +
"/Handlers/GenericCRUDHandler.aspx?sp=sp_deladdresses"
,
data: encodePlus(kendo.stringify(options.data)),
async:
false
,
type:
"POST"
,
success:
function
(response) {
addressesDataSource.read();
},
error:
function
(response) {
alert(response.responseText);
addressesDataSource.cancelChanges();
}
});
},
parameterMap:
function
(options, operation) {
if
(operation !==
"read"
&& options.models) {
return
{ models: kendo.stringify(options.models) };
}
}
},
batch:
true
,
serverSorting:
true
,
schema: {
model: {
id:
"address_id"
,
fields: {
address_id: { type:
"number"
},
place: { type:
"string"
, validation: { required:
true
, required: { message:
"Company name is required"
} } },
country_id: {
type:
"number"
,
validation: {
requiredropdown_countryDropDownEditor:
function
(input) {
return
AddDropDownValidationUniqueMessageName(input,
"countryDropDownEditor"
,
"Country is required"
);
}
}
},
postcode: { type:
"string"
, validation: { required:
true
} },
state: { type:
"string"
, validation: { required:
false
} },
city: { type:
"string"
, validation: { required:
true
} },
address_line1: { type:
"string"
},
address_line2: { type:
"string"
},
address_line3: { type:
"string"
},
address_type_id: {
type:
"number"
,
validation: {
requiredropdown_address_type_editor:
function
(input) {
return
AddDropDownValidationUniqueMessageName(input,
"address_type_editor"
,
"Require address type"
);
}
}
},
addressDetails: { type:
"string"
},
country: { type:
"string"
}
}
},
parse:
function
(response) {
$.each(response,
function
(idx, elem) {
elem.addressDetails = elem.place +
", "
+ getCountryName(elem.country_id) +
", "
+ elem.postcode;
// elem.country = getCountryName(elem.country_id);
});
return
response;
}
}
});
After inspecting the provided code snippet, I can assume that the issue occurs because in the success function the read method is trying to be executed before the previous request is finished. Also, the example is using synchronised Ajax requests.
I can suggest instead of using the read method in the success function, to use the requestEnd event of the dataSource to call the read() method of the dataSource. Please have in mind to check the type of the request, to ensure that the read method will not be called when the initial request is read as this will create infinite loop:
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#events-requestEnd
requestEnd:
function
(e){
if
(e.type !=
'read'
){
dataSource.read();
}
}
I hope this will help to achieve the desired result.
Regards,
Stefan
Telerik by Progress
Stefan,
Regarding your latest post - I am unsure what issue you addressing here. I think you have sent us a fix for a different issue?
Please can reread all posts from my original on the 6th September. To summarise - after create, update and destroy operations we currently reread the data - addressesDataSource.read() which we know is not necessary and will has performance issues. We would like to implement an alternative.
If we remove the unnecessary read in the success then we need some additional code to complete the synchronisation of client side data. We CANNOT send backup the current record in the same format as expected by the read, as this would require too many changes at the server end for us.
For a CREATE we can change our server end code to return in the response the id value for the new record. For UPDATE and DESTROY can also change our server code to return in the response the id value of the original record. Please can you provide alternative example code which uses the id value to complete synchronization in these cases.
My post was for the issue in this ticket.
Apologies if my answer was not clear enough.
From the described scenario I can confirm that based on the controller implementation, the Grid can work as expected if after every create, update or destroy the read method is called again (it is not very efficient approach but as the controller, implementation cannot be changed it is acceptable).
The suggested approach in my previous post address the issue that because of the synchronise Ajax the read method is not successfully called after every create, update and destroy. That is why I suggest to not call it in the success function, but instead to use the requestEnd event of the DataSource to call the read method.
If this approach does not resolve the issue, please send a runnable example so we can investigate further and provide a suggestion best suited for it.
Regards,
Stefan
Telerik by Progress
Stefan,
I am not sure if something is being lost in translation.
What I have in place at the moment is working with a reread in the success. I do NOT want to have a reread anywhere after the response whether that be in the success function or requestEnd - this is a clumsy inefficient way of getting the client fully in sync.
If we additionally pass back the record ID in the response is there a way to complete the sychronisation? The record already exists on the client so can I use this and the record ID to manually complete the synchronization?
regards,
Gary
After additional investigation and testing, I can suggest instead of calling the read method, to call options.success and pass the option.data as a parameter. This will ensure that the data will be in sync. Please have in mind that on , you have to manually add the returned ID from the server to the options.data object:
success:
function
(response) {
options.success(options.data);
//addressesDataSource.read();
}
I hope this approach will help to keep the data in sync and to remove the unnecessary read method.
Regards,
Stefan
Telerik by Progress
Stefan,
Thanks for your perseverance with this issue. In the end we have gone with the standard approach. We have managed to change our server side code without too many changes. We are now returning updated data to the client:
success: function (result) {
var JSONresult = JSON.parse(result);
options.success(JSONresult.models);
}
A point to note and this seems to born out by other posts I have seen: there does not seem to be anywhere on www.telerik.com documenting the implementation requirements for CUD operations to be synched properly i.e. data is returned to the client in the same format as expected by the read operation that is then passed to options.success() in the success function.
regards,
Gary
I'm glad to hear that the issue is resolved.
Regarding the feedback for our documentation: We do have examples showing that the data should be passed to the success function when a Local data or a custom transport are used:
http://docs.telerik.com/kendo-ui/framework/datasource/crud#local-or-custom-transport-crud-operations
If you have a suggestion how to optimise the article, your feedback is greatly appreciated.
Regards,
Stefan
Telerik by Progress