Попытка написать класс Javascript для динамического добавления новых данных в мой HTML. Нужно какое-то руководство - PullRequest
1 голос
/ 27 августа 2010

Вот то, к чему я стремлюсь:

HTML

<fieldset id="addmore">
   <p>blah</p>

   <a class="remove">remove me</a>
</fieldset>

<a class="add">add more fieldsets</a>

Javascript

var addmore = new AddMore($('fieldset'));
addmore.buildCache(/*this will pull the innerHTML of the fieldset*/);

// bind the buttons
addmore.bind('add', $('a.add'));
addmore.bind('remove', $('a.remove'));

В последнее время я обнаружил, что в моем HTML появилось намного больше «дополнительных» элементов, поэтому я пытался создать класс, который будет выполнять всю работу за меня, которую я смогу просто использовать во всех своих проектах. Надеюсь, что приведенный выше код будет всем, что я должен добавлять каждый раз, а затем все остальное будет сделано для меня.

Я подгонял эту штуку, так что, с головы до головы, вот что должен сделать класс:

  • Примените привязки jQuery к предоставленным объектам 'button', чтобы мы могли добавлять / удалять наборы полей
  • Когда добавляется новый набор полей, мы должны вызвать функцию связывания, чтобы сработала кнопка «a.add» нового набора полей (я обнаружил, что функция .live () jQuery по какой-то причине глючит, и попробуйте чтобы избежать этого)
  • Мы надеемся, что это будет сделано без утечек памяти:}

Класс Javascript

/*
   Class to handle adding more data to the form array

   Initialise the class by passing in the elements you want to add more of
   Then bind 'add' and 'remove' buttons to the functions and the class will do the rest
*/

/*
   Pass the jQuery object you want to 'addmore' of
   Ex: var x = new AddMore($('fieldset.addmore'));
*/
function AddMore($element)
{
   if (!$element || typeof($element) != 'object')
      throw 'Constructor requires a jQuery object';

   this.element = $element; // this is a jQuery object
   this.cache   = null;
}

/*
   Supply clean HTML to this function and it will be cached
   since the cached data will be used when 'adding more', you'll want the inputs to be emptied,
   selects to have their first option selected and any other data removed you don't want readded to the page
*/
AddMore.prototype.buildCache = function(fieldset)
{
   if (!fieldset)
      throw 'No data supplied to cache';

   this.cache = fieldset;
}

/*
   use this to create the initial bindings rather than jQuery
   the reason? I find .live() to be buggy. it doesn't always work. this usually means having to use a standard .bind()
   and then re-bind when we add in the new set

   that's what this class helps with. when it adds in the new data, it rebinds for you. nice and easy.
*/
AddMore.prototype.bind = function(type, $button)
{
   if (!type || !$button && (type != 'add' && type != 'remove'))
      throw 'Invalid paramaters';

   // don't reapply the bindings to old elements...
   if ($button.hasClass('addmore-binded'))
      return;

   // jQuery overwrites 'this' within it's scope
   var _this = this;

   if (type == 'add')
   {
      $button.bind('click', function()
      {
         _this.element.after(_this.cache);
      });
   }
}

Я собирался заставить метод .bind () (в моем классе) вызывать себя при добавлении нового набора полей для повторного применения привязки, но потерял уверенность в эффективности (скорость / память).

Как мне с этим справиться? У вас есть какие-либо указатели? Можете ли вы порекомендовать улучшения?

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 27 августа 2010

Для создания новых элементов DOM допускается, чтобы спецификация / параметры были следующими:

  1. простой HTML в виде строки (как в примере выше),
  2. функция, возвращающая либо элемент DOM, либо текст HTML.Вы можете пропустить проблемы bind () или live () , добавив элемент onclick при создании элемента HTML / в функции.Хотя делать это в области действия AddMore () было бы более утомительно, если бы не возвращался возвращаемый элемент DOM.
  3. вводит в метод помощника / фабрики (возможно, шаблон и имя / значение)пары) - отложите это, если вы уже не знаете достаточно паттернов.

Вариант № 1 кажется почти бесполезным, но № 3 может быть трудным, если у вас нет дополнительного времени.

Примечания:

  • Возможно, вы захотите использовать $(theNewDomElement).insertBefore(_this.button); вместо _this.element.after(theNewDomElement);, чтобы новые элементы добавлялись к концу списка.
  • На самом деле, для insertBefore () вы могли бы просто использовать this вместо _this.button, поскольку предположительно кнопка (или якорь) равна this, но тогда это ограничиваетфункциональность - просто сделайте его своего рода элементом DOM (или объектом jQuery, равным единице).
  • В большинстве случаев я бы предположил, что ваши элементы DOM представляют данные, которые вы хотите сохранить / отправить /передать на ваш сервер, так что предоставьте также функцию перед удалением.Даже позволяют функции пропустить удаление - как после Подтверждение () .

Удачи.

0 голосов
/ 27 августа 2010

В простейшей форме вы можете сделать что-то вроде этого:

var html = '{put html to add each time here}';

$('.add').click(function() {
    $(html).insertAfter($('fieldset').last());
    return false;
});

$('.remove').live('click', function() {
    $(this).parent().remove();
    return false;
});

Возможно, вам придется настроить его в соответствии с вашими потребностями, но это должно выполнить то, что вы описали в своем примере.

Обновление: извините, при удалении следует использовать метод live.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...