我编写了一个javascript文件:
$(function() {
return $(".ajax-form").on("ajax:success", function(e, data, status, xhr) {
var model_name;
model_name = $(this).data('model-name');
console.log('ajax form success');
if (model_name === 'contact') {
return $('#modal-alert-contact').modal('show');
} else {
return $('#modal-alert-demo').modal('show');
}
}).bind("ajax:error", function(e, xhr, status, error) {
var elm, messages, model_name;
model_name = $(this).data('model-name');
console.log('ajax form error');
console.log(model_name);
if (model_name === 'contact') {
if (xhr.responseJSON["email"]) {
elm = $('.alert-contact-fields');
messages = [];
$.each(xhr.responseJSON, function(id, error_messages) {
return messages.push(("<li><strong class='titleize'>" + id + "</strong> - can't be blank</li>").replace(/_/g, " "));
});
elm.find('.messages').html(messages);
return elm.removeClass('hide');
} else {
elm = $('.alert-contact-fields');
return elm.addClass('hide');
}
} else {
if (xhr.responseJSON["company_name"]) {
elm = $('.alert-demo-fields');
messages = [];
$.each(xhr.responseJSON, function(id, error_messages) {
return messages.push(("<li><strong class='titleize'>" + id + "</strong> - can't be blank</li>").replace(/_/g, " "));
});
elm.find('.messages').html(messages);
return elm.removeClass('hide');
} else {
elm = $('.alert-demo-fields');
return elm.addClass('hide');
}
}
});
});
我发现它很乱,并重复相同的代码。 我想做的就是这部分:
messages = [];
$.each(xhr.responseJSON, function(id, error_messages) {
return messages.push(("<li><strong class='titleize'>" + id + "</strong> - can't be blank</li>").replace(/_/g, " "));
});
elm.find('.messages').html(messages);
return elm.removeClass('hide');
我希望那部分成为一个函数,在我这样做之后,我将调用该函数在我的函数上使用它。是否有可能或者有一些技术来改进我的编码结构?
谢谢!
答案 0 :(得分:2)
我想你想要这样的东西:
$(function() {
var myform = $(".ajax-form");
var makeMessages = function(json) {
return $.map(json, function(error_messages, id) {
return ("<li><strong class='titleize'>" + id + "</strong> - can't be blank</li>").replace(/_/g, " ");
});
};
myform.on('ajax:success', function(e, data, status, xhr) {
var modal_to_show = ($(this).data('model-name') === 'contact') ? '#modal-alert-contact' : '#modal-alet-demo';
return $(modal_to_show).modal('show');
});
myform.on('ajax:error', function(e, xhr, status, error) {
var fields;
if ($(this).data('model-name') === 'contact') {
fields = $('.alert-contact-fields');
if (xhr.responseJSON["email"]) {
return fields.find('messages').html(makeMessages(xhr.responseJSON)).end().removeClass('hide');
}
return fields.addClass('hide');
}
fields = $('.alert-demo-fields');
if (xhr.responseJSON["company_name"]) {
return fields.find('.messages').html(makeMessages(xhr.responseJSON)).end().removeClass('hide');
}
return fields.addClass('hide');
});
});
makeMessages是一个接受json对象并返回一组字符串的函数; map()是比每个()更好的函数,因为它不需要中间数组来保存值。
'success'处理程序显示了'三元运算符'的使用,也称为条件表达式。你想知道要显示哪个模态:这是你如何选择它,然后只有一个'show'操作。它更容易调试。
对于'error'处理程序,每次设置消息时,只需使用JSON调用makeMessages()并获取所需的字符串数组。因为您必须在alert - * - fields中找到messages字段,所以我调用end()将当前jquery上下文返回一次搜索(从'find'到初始$()调用),然后调用'show'相反。
由于您在选定的成功操作结束时调用'return',因此根本不需要'else'语句。他们是噪音。要么你的代码做了它的事情,要么它落到下一个阶段。
你可以删除我的fields =
集合操作,因为每个节目只会被调用一次,因此重复这些操作是无害的。但是这明确了你正在做的哪个地区。
如果你想疯狂地关注你正在做的事情,把所有的决策都放在首位(要做什么,要展示什么),并使其余的代码纯机器,'如何'部分代码。 '错误'处理程序变为:
myform.on('ajax:error', function(e, xhr, status, error) {
var handler = (($(this).data('model-name') === 'contact') ?
{ 'fieldclass': '.alert-contact-fields', 'objname': 'email' } :
{ 'fieldclass': '.alert-demo-fields', 'objname': 'company_name' });
var fields = $(handler.fieldclass);
if (xhr.responseJSON[handler.objname]) {
return fields.find('.messages').html(makeMessages(xhr.responseJSON)).end().removeClass('hide');
}
return fields.addClass('hide');
});
此时'makeMessages()'变成了一个漂亮,方便的函数,因为它显示了(和名称!好名字对维护很重要)你正在用JSON对象做什么。
一个(好的,两个)最后的替代方案:
myform.on('ajax:error', function(e, xhr, status, error) {
var drawResults = function(fieldclass, objname) {
var fields = $(fieldclass);
if (xhr.responseJSON[objname]) {
return fields.find('messages').html(makeMessages(xhr.responseJSON)).end().removeClass('hide');
}
return fields.addClass('hide');
};
return ($(this).data('model-name') === 'contact' ?
drawResults('.alert-contact-fields', 'email') :
drawResults('.alert-data-fields', 'company_name'));
/* Absolutely minimal alternative, but some people find
* using the apply method obfuscating. */
return drawResults.apply(this, $(this).data('model-name') === 'contact' ?
['.alert-contact-fields', 'email'] :
['.alert-data-fields', 'company_name']);
});
不是预先使用字段和决策,而是将所有决策制定在最后,并描述一旦做出决定后会发生什么。这使用了更熟悉的调用函数的语法。重要的是要看到drawResults()已经可以访问xhr对象,因此没有必要将其传入。
最后一个可能的提取是将$(this).data('model-name') === 'contact'
转换为函数,例如isDemo()
,这样代码只会发生一次并且名称也很好。