Проблема с поддержанием области видимости с помощью шаблона jQuery / module - PullRequest
3 голосов
/ 30 августа 2011

Я только начинаю использовать шаблоны модулей (благодаря оригинальному руководству Кристиана Хайльмана), чтобы упорядочить мой jQuery, и у меня возникает странная проблема.Рассмотрим следующий код JavaScript:

var Gallery = function(){

  var $obj, $thumbs, $mainPic;

  function init($e){

    $obj = $e;
    $thumbs = $obj.find('.thumbnail');
    $mainPic = $obj.find('.main-pic');

    $obj.find($thumbs).bind('click',updateMainPic);

  };

  function updateMainPic() {
    $thumbs.removeClass('selected');
    $thumb = $thumbs.filter(this);
    $thumb.addClass('selected');
    newPicUrl = $thumb.data('src');    
    $mainPic.attr('src',newPicUrl);    
  };

  return {
    init:init
  }

}();

, который включен и используется в следующем HTML:

<div id="gallery1">
  <img src="" class="main-pic">
  <ul>
    <li class="thumbnail" data-src="photo1.jpg">Photo 1</li>
    <li class="thumbnail" data-src="photo2.jpg">Photo 2</li>
    <li class="thumbnail" data-src="photo3.jpg">Photo 3</li>
    <li class="thumbnail" data-src="photo4.jpg">Photo 4</li>
  </ul>
</div>
<script type="text/javascript">
  Gallery.init($('#gallery1'));
</script>

<div id="gallery2">
  <img src="" class="main-pic">
  <ul>
    <li class="thumbnail" data-src="photo1.jpg">Photo 1</li>
    <li class="thumbnail" data-src="photo2.jpg">Photo 2</li>
    <li class="thumbnail" data-src="photo3.jpg">Photo 3</li>
    <li class="thumbnail" data-src="photo4.jpg">Photo 4</li>
  </ul>
</div>
<script type="text/javascript">
  Gallery.init($('#gallery2'));
</script>

Проблема, с которой я сталкиваюсь, заключается в том, что нажатие на миниатюры на # gallery1поменяйте местами изображение # gallery2, но # gallery2 работает как положено.Казалось бы, переменная $ obj распределяется между экземплярами, но я подумал, что она осталась незаметной для частного экземпляра функции.

Любые советы о том, как получить эту область должным образом и работать, будут с благодарностью.

Ответы [ 3 ]

4 голосов
/ 30 августа 2011

Проблема в том, что Галерея - это синглтон. В тот момент, когда вы вызываете второй init, вы заменяете внутреннюю переменную $ obj.

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

0 голосов
/ 01 сентября 2011

Шаблон модуля больше предназначен для использования синглтон.Каждый раз, когда вы вызываете ваш метод init, вы переопределяете переменную $ obj на переданный $ e.Так что просто отбросьте $ obj, переместите два других в init и передайте три параметра updateMainPic.Если вам нужны указатели на основе экземпляров, пусть ваш singleton возвращает прототипную функцию, которую вы можете создавать экземпляры и привязывать непосредственно к событию dom click.

0 голосов
/ 30 августа 2011

Я немного поэкспериментировал с вашим сценарием, пытаясь понять, можно ли использовать шаблон модулятора; и похоже, что во время связывания возникает огромное препятствие. Становится очень сложно определить область действия «this» внутри функции updateMainPic (). Даже с такой мощной библиотекой, как underscore.js , с функцией _.bind (), которая позволяет связываться с объектом, этот сценарий не может легко преодолеть.

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

$('li.thumbnail').bind('click', function() {
    $(this).closest('div').find('.main-pic').attr('src', $(this).attr('data-src'));
    $(this).addClass('selected');
    $(this).siblings().removeClass('selected');
});
...