Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 17.09.2013, 17:21
Кандидат Javascript-наук
Отправить личное сообщение для FanAizu Посмотреть профиль Найти все сообщения от FanAizu
 
Регистрация: 08.03.2011
Сообщений: 148

Фабрика виджетов jQuery UI
Подскажите, пожалуйста. Читаю вот здесь http://jquery.page2page.ru/index.php...D0%BE%D0%B2_UI

Вот цитата из статьи "Когда вы делаете плагин с помощью $.widget(), jQuery UI создает javascript-объект, содержащий все настройки по умолчанию и методы плагина. Этот объект называют прототипом плагина. При установке плагина на определенный элемент, делатся отдельная копия этого прототипа, которая будет хранить состояние плагина именно на этом элементе. Такую отдельно взятую копию прототипа называют экземпляром плагина.".

Правильно ли я понимаю, что это означает, что делается копия объекта-прототипа для каждого элемента на странице, для которого вызывается плагин? То есть, получается, что в создаваемую копию помимо свойств из объекта прототипа, копируются и методы из объекта-прототипа? То есть в каждой копии объекта прототипа, содержатся все свойства и все методы объекта прототипа?
Например, если в объекте прототипе есть метод hello, то если плагин будет вызван на 10 элементах страницы, то будет 10 копий объекта прототипа и в каждой копии будет содержаться свой метод hello? Или же метод hello в каждой копии будет ссылаться на одну и ту же ф-цию?

И подскажите, пожалуйста, какие ещё есть конструкторы плагинов помимо jQuery фабрики виджетов. Спасибо.
Ответить с цитированием
  #2 (permalink)  
Старый 18.09.2013, 11:21
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Введение фабрики виджетов в jQueryUI имело несколько целей.

1) Задействовать механизм наследования для виджетов
2) Обеспечить внешние API для виджетов
3) Снабдить каждый виджет стандартным набор функций вроде enable/disable и подобных
4) Структурировать и сделать предсказуемым код виджета

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

Что касается наследования.
Прототип базового виджета и нового виджета смешиваются в один объект в момент наследования. Затем этот объект становится прототипом конструктора вашего виджета.

Дальше мы имеем обычный конструктор с прототипом.
То есть 10 экземпляров виджета HELLO будут иметь общий набор методов в прототипе. То есть не каких копий прототипа для каждого экземпляра не создается. Прототип на то и прототип чтобы быть общим.

В принципе у меня нет претензий к фабрике виджетов, все достаточно оптимально.


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

Механизьм наследования можно подробно рассмотреть вот здесь.
48я обьявление конструктора
61я подмешиваем статические свойства
71я Получаем прототип базового виджета (по умолчанию Widget )
76я оборачиваем методы оберткой чтобы ониначали поддерживать метод super
105я смешиваем базовый прототип с твоим а результат пишем в constructor.prototype
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 18.09.2013 в 11:57.
Ответить с цитированием
  #3 (permalink)  
Старый 18.09.2013, 14:16
Кандидат Javascript-наук
Отправить личное сообщение для FanAizu Посмотреть профиль Найти все сообщения от FanAizu
 
Регистрация: 08.03.2011
Сообщений: 148

А что тогда означает эта фраза "При установке плагина на определенный элемент, делатся отдельная копия этого прототипа"?
Ответить с цитированием
  #4 (permalink)  
Старый 18.09.2013, 16:07
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

По моему не удачно написано в документации.
В исходниках нет нечего подобного.

Посмотри сам, нет не одной строчки ответственной за копирование прототипа при создании экземпляров

1)запускается конструктор
2) констроктор обнаруживает что в this Нет this._createWidget и вызывает new constructor( options, element )
3) теперь уже вызванный через new конструктор обнаруживает что в this есть _createWidget, ведь это уже не функция а конструктор обьекта, обнаружив это он вызывает createWidget


constructor = $[ namespace ][ name ] = function( options, element ) {
		// allow instantiation without "new" keyword
		if ( !this._createWidget ) {
			return new constructor( options, element );
		}

		// allow instantiation without initializing for simple inheritance
		// must use "new" keyword (the code above always passes args)
		if ( arguments.length ) {
			this._createWidget( options, element );
		}
	};


Собственно к этому моменту объект уже создан, в прототие общие методы. Дальше просто идет инициализация виджета отвечает за нее createWidget

Create widget занимается тем что подготавливает Опции к передачи в INIT
а так же инициализирует некоторые свойства вроде this.element
сохраняет ссылку на обьект созданный конструктором в data ( $.data( element, this.widgetFullName, this ); )
вызывает init и create,
поджигает событие "create"


_createWidget: function( options, element ) {
		element = $( element || this.defaultElement || this )[ 0 ];
		this.element = $( element );
		this.uuid = uuid++;
		this.eventNamespace = "." + this.widgetName + this.uuid;

		this.options = $.widget.extend( {},
			this.options,
			this._getCreateOptions(),
			options );

		this.bindings = $();
		this.hoverable = $();
		this.focusable = $();

		if ( element !== this ) {
			$.data( element, this.widgetFullName, this );
			this._on( true, this.element, {
				remove: function( event ) {
					if ( event.target === element ) {
						this.destroy();
					}
				}
			});
			this.document = $( element.style ?
				// element within the document
				element.ownerDocument :
				// element is window or document
				element.document || element );
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
		}

		this._create();
		this._trigger( "create", null, this._getCreateEventData() );
		this._init();
	},
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 18.09.2013 в 17:00.
Ответить с цитированием
  #5 (permalink)  
Старый 22.01.2014, 17:14
Кандидат Javascript-наук
Отправить личное сообщение для FanAizu Посмотреть профиль Найти все сообщения от FanAizu
 
Регистрация: 08.03.2011
Сообщений: 148

возник ещё один вопрос по фабрике, подскажите, пожалуйста.
например, я создал виджет product с использованием фабрики виджетов.

в объекте-реализации виджета есть следующий метод, который вызывается сразу после установки виджета на диве:
{
	findElement : function()
	{
		this.name = this.find('.product--name');
		this.cost = this.find('.product--cost');
	}
}


То есть находим элемент с классом product--name внутри виджета и сохраняем в нашем объекте.

вот верстка сего виджета:
<div class="product">
	<div class="product--name">
		
	</div>
</div>


на странице 3 продукта

<div class="product">
	<div class="product--name">
		
	</div>
	<div class="product--cost">
		
	</div>
</div>
<div class="product">
	<div class="product--name">
		
	</div>
	<div class="product--cost">
		
	</div>
</div>
<div class="product">
	<div class="product--name">
		
	</div>
	<div class="product--cost">
		
	</div>
</div>


вызываю инициализацию виджета
$('.product').product();


теперь возникла задача: по клику на <div class="product--name"> product--cost должен закрыться.
вот методы, которые это делают:
{
	onNameClick : function()
	{
		this.name.on('click', this.handleNameClick);
	},
	
	handleNameClick : function(event)
	{
		this.product--cost.css({display : 'none'});
	}
}


Естественно product--cost не скроется т.к. устанавливая обработчик клика handleNameClick, он вызывается не как метод объекта, а как обычная ф-ция.

Можно, кончно, было реализовать это так:

{
	onNameClick : function()
	{
		this.name.on('click', this.handleNameClick);
	},
	
	handleNameClick : function(event)
	{
		$(event.currentTarget).parents('.product').find('.product--cost').css({display : 'none'});
	}
}


это будет работать, но вся моя идея заключается в том, что внутри метода findElement я хочу находить все элементы виджета и сохранять ссылки на эти элементы внутри экземпляра виджета, то есть в объекте.
я хочу один раз потратить время, найдя все элементы виджета(product--name, product--cost), а затем манипулировать этими элементами, не тратя времени на их поиск, как я делаю вот в этом куске кода:
$(event.currentTarget).parents('.product').find('. product--cost')

Конечно, можно ещё сделать вот так:
{
	onNameClick : function()
	{
		var copyOfThis = this;
		
		function handleNameClick(event)
		{
			copyOfThis.handleNameClick(event);
		}
		
		this.name.on('click', handleNameClick);
	},
	
	handleNameClick : function(event)
	{
		this.cost.css({display : 'none'});
	}
}


Замыкание, здорово, работает. Но есть одно неприятное для меня НО. При таком подходе, если будет, например, 1000 продуктов на странице, то ф-ция handleNameClick внутри метода onNameClick будет создана 1000 раз, то есть в памяти будет 1000 экземпляров
одной и той же ф-ции.

В общем я потратил уже не одну неделю, размышляя как же сделать правильно и максимально удобно, но не смог найти решения, которое бы устроило меня.
Может в фабрике уже давно есть решение данного момента, а я и не знаю о нем? Либо, пожалуйста, может у вас есть идеи на сей счет? Заранее благодарю.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
хочу инвайт на хабр macdack Оффтопик 45 28.07.2013 23:18
Работа для знатока jQuery virtualbrest Работа 0 24.07.2013 16:05
Динамически загружаемая jQuery и jQuery-функции в одном файле 67bytes Общие вопросы Javascript 6 06.03.2013 09:01
Вопрос поддержки старых методов jQuery antonM jQuery 1 04.10.2012 00:08
2 разных модуля на jQuery - как подключить? finder jQuery 4 23.03.2012 22:29