Можно ли использовать шаблон модуля Javascript для синглетонов, а также для объектов, для которых время создания экземпляра многократно? - PullRequest
3 голосов
/ 22 июля 2010

У меня есть одна страница с двумя типами форм. У меня есть одна форма типа A наверху, а затем у меня есть 1 или более форм типа B под ней.

Я использую шаблон модуля + jQuery, чтобы связать все события в моих формах, обработать проверку, вызовы ajax и т. Д.

Является ли это предпочтительным / действительным способом определения синглтона, как в форме A, и класса объектов многократного использования, как в форме B? Они очень похожи, и я не уверен, нужно ли мне использовать свойство prototype, new или другой шаблон. Кажется, у меня все работает, но я боюсь, что мне не хватает какой-то ключевой ошибки.

Form A JavaScript выглядит так:

var MyProject.FormA = (function() {
  var $_userEntry;
  var $_domElementId;

  var validate = function() { 
    if($_userEntry == 0) {
      alert('Cannot enter 0!');
    } 
  }
  var processUserInput = function() {
    $_userEntry = jQuery('inputfield', $_domElementId).val();
    validate();
  }
  return {
    initialize: function(domElementId) {
      $_domElementId = domElementId;
      jQuery($_domElementId).click(function() {
        processUserInput();
      }
    }
  }

})();
jQuery(document).ready(function() {
  MyProject.FormA.initialize('#form-a');
});

Form B, который инициализируется один или несколько раз, определяется следующим образом:

var MyProject.FormB = function() {
  var $_userEntry;
  var $_domElement;

  var validate = function() { 
    if($_userEntry == 0) {
      alert('Cannot enter 0!');
    } 
  }
  var processUserInput = function() {
    $_userEntry = jQuery('inputfield', $_domElement).val();
    validate();
  }
  return {
    initialize: function(domElement) {
      $_domElement = domElement;
      jQuery($_domElement).click(function() {
        processUserInput();
      }
    }
  }

};
jQuery(document).ready(function() {
  jQuery(".form-b").each(function() {
    MyProject.FormB().initialize(this);
  });
});

Ответы [ 2 ]

2 голосов
/ 22 июля 2010

Оба ваших модуля явно возвращают объекты, что исключает использование новых.

Наследование прототипа не совсем совместимо с методом, скрывающим ваши достижения по этому шаблону.Конечно, вы можете переписать это с помощью прототипа объекта формы с определенным на нем методом validate, но тогда этот метод будет видимым, и вы потеряете инкапсуляцию.

Вам решать, хотите ли вы низкий уровеньОбъем памяти и быстрая инициализация объектов прототипами (общие методы существуют только один раз, реализация выполняется за постоянное время) или инкапсуляция шаблона модуля, что приводит к небольшому снижению производительности (несколько идентичных идентичных методов, создание объектов замедляется, так как каждый метод должен бытьсоздается каждый раз)

В этом случае я бы предположил, что разница в производительности незначительна, поэтому выбирайте все, что вам нравится.Лично я бы сказал, что между ними слишком много дублирования, и я был бы склонен объединить их.Тебе действительно нужен A, чтобы быть одиночкой?Какова опасность того, что он был дважды случайно создан?Похоже, что это может быть чрезмерной инженерии для этой проблемы.Если вам действительно нужен синглтон, я бы обернул класс non-singleton (B) следующим образом:

var getSingleton = function() {
    var form = MyProject.FormB();
    form.initialize("#form-a");
    console.log("This is the original function");
    getSingleton = function() {     
        console.log("this is the replacement function");
        return form;
    }
    return form;
}
1 голос
/ 22 июля 2010

Я думаю, вам просто нужно написать своего рода плагин jQ:

(function($) {
    $.fn.formValidator = function() {
        return $(this).each(function() {
            var $_domElement = $(this);
            $_domElement.click(function() {
                if($('inputfield', $_domElement).val() == 0) {
                    alert('Cannot enter 0!');
                }
            });
        });
    };
})(jQuery);

В этом случае вы расширите модуль методов элемента jQ и сможете использовать его для любого количества элементов настраница (для одного или нескольких элементов коллекции).Также он будет цепным.

Использование:

$('#form-a').formValidator();
$('.form-b').formValidator();

Или

$('#form-a, .form-b').formValidator();

Конечно, вы можете использовать модуль для хранения этой функции:

ProjectModule.formValidator = function(selector) {
    return $(selector).each(function() {
        var $_domElement = $(this);
        $_domElement.click(function() {
            if ($('inputfield', $_domElement).val() == 0) {
                alert('Cannot enter 0!');
            }
        });
    });
};

Использование:

ProjectModule.formValidator('#form-a, .form-b');
...