简体   繁体   English

在函数上调用函数-jQuery

[英]Calling a function on a function - Jquery

I have coded a javascript file: 我已经编码了一个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');
      }
    }
  });
});

and I found it out messy, and repeating same codes. 我发现它很乱,并重复了相同的代码。 What I'm want to do is this part: 我想做的是这一部分:

        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');

I want that part to be a function, and after I do that, I will call that function to use it on my function. 我希望该部分成为一个函数,然后,我将调用该函数在我的函数上使用它。 Is it possible or there's some technique to improve my coding structure? 是否有可能或有某种技术可以改善我的编码结构?

Thanks! 谢谢!

I think you want something like this: 我想你想要这样的东西:

$(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 is a function that takes the json object and returns a set of strings; makeMessages是一个接受json对象并返回一组字符串的函数; map() is a much better function for that than each(), because it requires no intermediate array to save the values. map()的功能比each()更好,因为它不需要中间数组来保存值。

The 'success' handler shows the use of the 'ternary operator', also known as a conditional expression. “成功”处理程序显示“三元运算符”的使用,也称为条件表达式。 You want to know which modal to show: this is how you pick it, then have one and only one 'show' operation. 您想知道要显示的模态:这是您如何选择它,然后执行一个且只有一个“ show”操作。 It's way easier to debug. 它更容易调试。

For the 'error' handler, each time you set the messages, you just call makeMessages() with your JSON and get back the array of strings you want. 对于“错误”处理程序,每次设置消息时,只需使用JSON调用makeMessages()并获取所需的字符串数组即可。 Because you had to find the messages field inside the alert-*-fields, I call end() which pops the current jquery context back one search (from the 'find' to the initial $() call) and then call 'show' on it instead. 因为您必须在alert-*-fields中找到messages字段,所以我调用end(),它将当前的jquery上下文弹出一次搜索(从“查找”到最初的$()调用),然后调用“ show”代替它。

Since you call 'return' at the end of a chosen successful operation, there is no need at all for 'else' statements. 由于您在选定的成功操作结束时调用“返回”,因此根本不需要“其他”语句。 They're noise. 他们是噪音。 Either your code does its thing, or it falls through to the next stage. 您的代码要么执行其任务,要么进入下一阶段。

You could remove my fields = set operations, since performance-wise each will only be called once, so it's harmless to have that repetition. 您可以删除我的fields = set操作,因为从性能角度来看,每个操作仅被调用一次,因此重复该操作是无害的。 But this makes explicit which region you're working in. 但是,这可以清楚地表明您正在工作的区域。

If you want to get insanely dense about what you're working on, put all the decision-making up top (what to work on, what to show), and make the rest of the code pure machinery, the 'how' part of your code. 如果您想疯狂地处理自己正在做的事情,请将所有决策放在首位(要做什么,要显示什么),然后将其余的代码变成纯机器,“如何”部分您的代码。 The 'error' handler becomes this: “错误”处理程序变为:

    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');
    });

At which point 'makeMessages()' just becomes a nice, convenient function because it shows (and names! Good names are always important to maintenance) what you're doing with the JSON object. 此时,“ makeMessages()”将成为一个不错的,方便的函数,因为它显示(和名称!好名称对于维护而言总是很重要的)对JSON对象的操作。

One (well, two) last alternatives: 最后一个选择(有两个):

    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']);
    });

Rather than use fields and decisions up front, this puts all the decision making at the end, and describes what will happen once the decision is made up front. 与其使用字段和决策,不如将所有决策放在最后,并描述一旦决策就将发生什么。 This uses a more familiar syntax of calling a function. 这使用了更熟悉的调用函数的语法。 It's important to see that drawResults() has access to the xhr object already, so it isn't necessary to pass it in. 重要的是要知道drawResults()已经可以访问xhr对象,因此没有必要传递它。

One last possible extraction is to turn $(this).data('model-name') === 'contact' into a function, like isDemo() , so that code only happens once and is also well-named. 最后一种可能的提取方法是将$(this).data('model-name') === 'contact'转换为一个函数,例如isDemo() ,这样代码只发生一次并且也被很好地命名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM