jQuery和“有组织的代码”

时间:2008-10-30 21:17:34

标签: javascript jquery code-organization

我最近一直在努力了解组织jQuery代码的最佳方法。我之前提出了另一个问题,我认为我不够具体(found in this question here)。

我的问题是你做一个应用程序越丰富,你的客户端就越快失控。考虑一下这种情况......

//Let's start some jQuery
$(function() {        
    var container = $("#inputContainer");

    //Okay let's list text fields that can be updated
    for(var i=0; i < 5; i++) {

        //okay let's add an event for when a field changes
        $("<input/>").change(function() {

            //okay something changed, let's update the server
            $.ajax({
                success:function(data) {

                    //Okay - no problem from the server... let's update
                    //the bindings on our input fields
                    $.each(container.children(), function(j,w) {

                        //YIKES!! We're deep in here now!!
                        $(w).unbind().change(function() {

                            //Then insanity starts...

                        }); // end some function

                    }); //end some loop

                } // what was this again?

            }); //ending something... not sure anymore

        }).appendTo(container); //input added to the page... logic WAY split apart

    }; //the first loop - whew! almost out!

});  //The start of the code!!

现在这种情况并非不可能。我并不是说这是正确的方法,但是在jQuery命令中发现自己的几个级别并开始怀疑在屏幕开始融化之前可以添加多少逻辑并不罕见。

我的问题是人们如何管理或组织限制代码的复杂性?

I listed how I'm doing it in my other post ...

8 个答案:

答案 0 :(得分:49)

只想添加前面提到过的内容:

$.each(container.children(), function(j,w) {
    $(w).unbind().change(function() { ... });
});

可以优化为:

container.children().unbind().change(function() { ... });

关键是链接,这是简化代码的好方法。

答案 1 :(得分:18)

到目前为止,我这样做:

// initial description of this code block
$(function() {        
    var container = $("#inputContainer");

    for(var i=0; i < 5; i++) {
        $("<input/>").changed(inputChanged).appendTo(container);
    }; 

    function inputChanged() {
        $.ajax({
            success: inputChanged_onSuccess
        });
     } 

     function inputChanged_onSuccess(data) {
        $.each(container.children(), function(j,w) {
          $(w).unbind().changed(function() {
             //replace the insanity with another refactored function
          });
        });
      }
});

在JavaScript中,函数是第一类对象,因此可以用作变量。

答案 2 :(得分:8)

嗯,首先,拥有一个理解javascript的好IDE可以提供很大帮助,即使只是为了识别匹配的分界线(括号,parens等)。

如果你的代码开始变得那么复杂,可以考虑制作自己的静态对象来组织乱七八糟的东西 - 你不必非常努力地保持一切匿名。

var aCustomObject = {
    container: $("#inputContainer"),
    initialize: function()
    {
        for(var i=0; i < 5; i++)
        {
            $("<input/>").changed( aCustomObject.changeHandler );
        }
    },
    changeHandler: function( event )
    {
        $.ajax( {success: aCustomObject.ajaxSuccessHandler} );
    },
    ajaxSuccessHandler: function( data )
    {
        $.each( aCustomObject.container.children(), aCustomObject.updateBindings )
    },
    updateBindings: function( j, w )
    {
        $(w).unbind().changed( function(){} );
    }
}
aCustomObject.initialize();

答案 3 :(得分:4)

在我看来,BaileyP描述的方法是我用来开始的,然后我通常将所有内容抽象为更多可重用的块,特别是当某些功能扩展到更容易将其抽象为插件然后具有它特定于一个站点。

只要您将大块代码保存在单独的文件中并进行良好编码,您就可以得到一些非常干净的语法。

// Page specific code
jQuery(function() {
    for(var i = 0; i < 5; i++) {
         $("<input/>").bindWithServer("#inputContainer");
    }
});

// Nicely abstracted code
jQuery.fn.bindWithServer = function(container) {
     this.change(function() {
             jQuery.ajax({
                 url: 'http://example.com/',
                 success: function() { jQuery(container).unbindChildren(); }
             });
     });
}
jQuery.fn.unbindChildren = function() {
    this.children().each(function() {
        jQuery(this).unbind().change(function() {});
    });
}

答案 4 :(得分:4)

有人撰写了关于类似主题的帖子。

jQuery Code Does not have to be Ugly

例如,作者Steve Wellens建议不要使用匿名函数,因为它使代码更难阅读。相反,将函数引用推送到jQuery方法中,如下所示:

$(document).ready(DocReady);

function DocReady()
{       
    AssignClickToToggleButtons();
    ColorCodeTextBoxes();
}

本文的另一个要点是将jQuery对象分配给具体变量,这使得代码看起来更干净,更少依赖于实际的jQuery对象,并且更容易分辨出某行代码正在做什么:

function ColorCodeTextBoxes()
{
    var TextBoxes = $(":text.DataEntry");

    TextBoxes.each(function()
    {
        if (this.value == "")
            this.style.backgroundColor = "yellow";
        else
            this.style.backgroundColor = "White";
    });
}

答案 5 :(得分:2)

将一些匿名函数粘贴到全局范围函数(或您自己的“命名空间”对象)中,尤其是重用函数,它开始看起来不像您发布的那样。有点像你所链接的。

答案 6 :(得分:2)

我描述了我的方法in your other post。简短形式:

  • 不要混用javascript和HTML
  • 使用类(基本上开始将您的应用程序视为小部件集合)
  • 只有一个$(文件).ready(...)块
  • 将jQuery实例发送到您的类中(而不是使用插件)

答案 7 :(得分:2)

使用http://coffeescript.com/;)

$ ->
  container = $ '#inputContainer'
  for i in [0...5]
    $('<input/>').change ->
      $.ajax success: (data) ->
        for w in container.children()
          $(w).unbind().change ->
            alert 'duh'