How can I keep MVC JQuery Ajax POSTs DRY?
I'm using Ajax to POST updates to the server:
$("#my-check-box").change(function () {
var value = $(this).attr("checked");
var url = '<%: Url.Routes().MyAction() %>';
$.ajaxSetup({ cache: false });
$.post(url, { **myActionParameterName**开发者_运维技巧: value }, function (data) {
if (data.result != "success") {
alert(data.error);
}
});
});
I don't want to write the parameter name on the client side (in case it changes) but is there a way to avoid doing this?
Simple answer: no. At the end of the day, your AJAX needs to know what to call the parameter one way or another.
What you're talking about is abstraction, and not the "Don't Repeat Yourself" strategy. DRY means "Don't repeat your logic more than once," not "Don't reference variables." If that were the case, you wouldn't be able to make any sort of reference to variables or parameters because you're technically repeating the name of the variable.
You're going to have to reference something, and that something will be referenced more than once, once client side and once server side. You can abstract it into something else, sure, but at the end of the day, it's probably easiest to just reference your action parameter and don't worry about it.
Refactoring would involve a simple Find/Replace anyway, which wouldn't change under any sort of abstraction.
Now, if you're referencing that JSON object more than once or constructing it oddly multiple times in your JavaScript, that's when DRY comes into play and you should create a method where you can pass in the data to construct it.
Here is what I do: I Cannot take all the credit as I found parts from an example.
var varType;
var varUrl;
var varData;
var varContentType;
var varDataType;
var varProcessData;
//Generic function to call ASMX/WCF Service
function CallService()
{
$.ajax({
type : varType, //GET or POST or PUT or DELETE verb
url : varUrl, // Location of the service
data : varData, //Data sent to server
contentType : varContentType, // content type sent to server
dataType : varDataType, //Expected data format from server
processdata : varProcessData, //True or False
success : function(msg) {//On Successfull service call
ServiceSucceeded(msg);
},
error: ServiceFailed// When Service call fails
});
}
Then have a function for the success
function ServiceSucceeded(result) {//When service call is successful
....
}
Then a function for failures
function ServiceFailed(result) {
...
}
Then finally an example of calling the ajax function:
function GetWCFJSON() {
varType = "POST";
varUrl = "service/WCFService.svc/GetMyData";
varData = '{"States": "' + $('#ddlStates').val() + '"}';
varContentType = "application/json; charset=utf-8";
varDataType = "json";
varProcessData = true;
CallService();
}
I would recommend using jQuery.extend() functionality to simplify you calls and create a javascript api. Check out check out this video from MVC Conf
I use a stndard ajax call like this
//A standard ajax api call that takes in a set of options
//This uses the jQuery extend method to merge the supplied options with a set of defaults
(function ($) {
$.apiCall = function (options) {
var config = $.extend({
type: 'GET',
data: {},
contentType: 'application/x-www-form-urlencoded',
success: function () { },
error: function () { }
}, options);
$.ajax({
type: config.type,
url: config.url,
contentType: config.contentType,
data: config.data,
success: function (result) {
config.success(result);
},
error: function (result) {
config.error(result);
flashError('An error occured during the operation');
//Okay, so this last bit is kindof a problem. Your nice, sharable api should not be referencing something
// on the master page. So you could pass it all the way down. But that means you have to have this defined
// lots of places. Or you could create another js object to wrap this. There are several ways to do this and
// how you do it is up to you.
}
});
}
})(jQuery);
I then extend it with a api per entity
//User api object
//Uses the prototype method to make sure all objects of this type have required functions
var patientsApi = function () { }
userApi.prototype.getUsers = function (options,Id) {
var config = $.extend({
success: function () { },
error: function () { }
}, options);
$.apiCall({
url: '/Users/GetUser',
data:{ID:Id},
success: function (result) { config.success(result); }
});
}
You can then call from the page like this
var api = new userApi();
var UserId= $("#UserId").val();
api.getUsers({
success: function (result) {
//Do some stuff
}
},userId);
精彩评论