JQuery и "Организованный код" - PullRequest
50 голосов
/ 31 октября 2008

В последнее время я пытаюсь понять, как лучше организовать код jQuery. Я задал другой вопрос ранее, и я не думаю, что я достаточно конкретен ( в этом вопросе здесь ).

Моя проблема в том, что чем богаче вы подаете заявку, тем быстрее ваша клиентская сторона выходит из-под контроля. Рассмотрим эту ситуацию ...

//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 и начинаете задаваться вопросом, сколько еще логики можно добавить, прежде чем экран начнет плавиться.

Мой вопрос: как люди управляют этим или организуют, чтобы ограничить сложность своего кода?

Я перечислил, как я делаю это в моем другом посте ...

Ответы [ 8 ]

49 голосов
/ 01 ноября 2008

Просто хочу добавить к тому, что упоминалось ранее, что это:

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

можно оптимизировать до:

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

Это все о цепочках, отличный способ упростить ваш код.

18 голосов
/ 31 октября 2008

Пока я делаю это так:

// 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 функции являются первоклассными объектами и поэтому могут использоваться в качестве переменных.

8 голосов
/ 31 октября 2008

Ну, во-первых, хорошая IDE, которая понимает javascript, может очень сильно помочь, даже если просто определить совпадающие границы (фигурные скобки, скобки и т. Д.).

Если ваш код начинает действительно становиться таким сложным, подумайте над созданием собственного статического объекта для организации беспорядка - вам не нужно так усердно работать, чтобы сохранить анонимность.

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();
4 голосов
/ 02 февраля 2010

Кто-то написал пост на похожую тему.

jQuery-код Не обязательно должен быть безобразным

Например, автор, Стив Уэлленс, предлагает не использовать анонимные функции, поскольку это затрудняет чтение кода. Вместо этого вставьте ссылку на функцию в методы 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";
    });
}
4 голосов
/ 31 октября 2008

По моему мнению, метод, описанный 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() {});
    });
}
2 голосов
/ 28 октября 2010

Использование 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'
2 голосов
/ 12 ноября 2008

Я описал свой подход в вашем другом посте . Сокращенная форма:

  • не смешивайте JavaScript и HTML
  • использовать классы (в основном начинают видеть ваше приложение как набор виджетов)
  • имеет только один блок $ (document) .ready (...)
  • отправка экземпляров jQuery в ваши классы (вместо использования плагинов)
2 голосов
/ 31 октября 2008

Вставьте некоторые из функций anon в глобальные функции области видимости (или в свой собственный объект «пространство имен»), особенно в повторно используемые функции, и он станет менее похож на то, что вы опубликовали. Вроде того, с чем вы связаны.

...