Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   правильная передача ссылки на объект в классе (https://javascript.ru/forum/css-html/3435-pravilnaya-peredacha-ssylki-na-obekt-v-klasse.html)

belbek 18.04.2009 17:16

правильная передача ссылки на объект в классе
 
Я понимаю что this зависит от контекста
В функкции- классе есть несколько методов, некоторые используют дом-события, как правильно передавать ссылку на объект класса в котором эти методы реализованы, все путается this от событий, сами события, неужели везде замыкания делать, как-то неаккуратненько поллучается. Скажите, где почитать. Спасибо.

Riim 18.04.2009 17:27

Цитата:

Сообщение от belbek
передавать ссылку на объект класса

На экземпляр или на конструктор? Кто из них называется объектом класса?

И куда передавать? В обработчик события?

И пример кода если можно.

belbek 18.04.2009 17:34

вот весь код
 
function Tree(id)
{
	this.prepare(id);
	
}
Tree.prototype.prepare = function(id)
{
	var container = document.getElementById(id);
	var initLength = container.getElementsByTagName("li").length;
	for (var i = 0; i < initLength; i++) 
     document.getElementById(id).getElementsByTagName("li")[i].addEventListener("click", this.clickHandler, false);
	
}

Tree.prototype.clickHandler = function()
{
	
		if (this.getElementsByTagName("ul").length) 
		{
			this.removeChild(this.getElementsByTagName("ul")[0]);
		}
		else 
		{
			var clickedId = this.getAttribute("id");
			var xhr = new XMLHttpRequest();
			var url = "/base/loadTree?id="+clickedId;
			xhr.onreadystatechange = obj.processXML;
			xhr.open("get", url, true);
			xhr.send(null);
		}	
}
		
		
Tree.prototype.processXML = function()
{
				
				if (this.readyState != 4 || this.status != 200) return;
				var xml = this.responseXML;
				var length = xml.getElementsByTagName("item").length;
				var ul = document.createElement("ul");
				for (var i = 0; i < length; i++) 
				{
					var li = document.createElement("li");
					li.setAttribute("id", xml.getElementsByTagName("id")[i].firstChild.nodeValue);
					li.innerHTML = xml.getElementsByTagName('name')[i].firstChild.data;
					ul.appendChild(li);
					
				}
				document.getElementById(clickedId).appendChild(ul);
			
			
}

hogart 18.04.2009 17:44

Как-нибудь так:
Tree.prototype.prepare = function(id) {
	var t = this;
	var container = document.getElementById(id);
	var initLength = container.getElementsByTagName("li").length;
	for (var i = 0; i < initLength; i++) {
		document.getElementById(id).getElementsByTagName(" li")[i].addEventListener("click", function (evt) { t.clickHandler.apply(t, [t]), false);
	}
}


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

Riim 18.04.2009 17:45

А откуда в Tree.prototype.clickHandler
obj взялся?

Riim 18.04.2009 17:47

Цитата:

Сообщение от hogart
Как-нибудь так:

Да не там норм все. В Tree.prototype.clickHandler идет работа с LI который там и есть.

Riim 18.04.2009 17:48

Вам наверно нужно чтобы в Tree.prototype.processXML на this была ссылка на var xhr = new XMLHttpRequest(); ?
upd: а не она там и так есть
Так куда, что не передается то?

belbek 18.04.2009 17:51

сорри obj там случайно затесался
 
Т.е. вопрос, в общем как получить ссылку на Tree(желательно однократно), и где разместить код получения этой ссылки?

Riim 18.04.2009 18:01

Цитата:

Сообщение от belbek
Т.е. вопрос, в общем как получить ссылку на Tree(желательно однократно), и где разместить код получения этой ссылки?

Т. е. в любом методе нужно получать ссылку на текущий экземпляр? Обычно эта ссылка висит на this. А у вас случилось так, что в Tree.prototype.clickHandler на this висит LI, а в Tree.prototype.processXML на this ссылка на XMLHttpRequest. И в обоих методах нет доступа к текущему экземпляру. Правильно я понял проблему? Если нет, то объясните подробней, а то гадать приходится.

belbek 18.04.2009 18:05

да, совершенно верно
 
абсолютно точно

Riim 18.04.2009 18:31

Может стоит тогда ссылки на LI и XMLHttpRequest засылать как аргументы. Тогда в this будет то, что и должно в них быть. Или наоборот: первый аргумент - ссылка на текущий экземпляр, this - ссылка на LI/XMLHttpRequest.
Или вообще изврат: this - ссылка на объект с двумя свойствами, одно из которых ссылка на текущий экземпляр, а другое LI/XMLHttpRequest.

belbek 18.04.2009 19:29

Такое уже пробовал. В любом случае, спасибо.
 
Цитата:

Сообщение от Riim (Сообщение 17027)
Может стоит тогда ссылки на LI и XMLHttpRequest засылать как аргументы. Тогда в this будет то, что и должно в них быть. Или наоборот: первый аргумент - ссылка на текущий экземпляр, this - ссылка на LI/XMLHttpRequest.
Или вообще изврат: this - ссылка на объект с двумя свойствами, одно из которых ссылка на текущий экземпляр, а другое LI/XMLHttpRequest.

Такое уже пробовал. В любом случае, спасибо.

x-yuri 23.04.2009 21:45

а это не самый распространенный путь в memory leak'и?
node.on... = function() {
    ...node...
}

я так подозреваю, что не обязательно даже использовать node внутри функции

x-yuri 23.04.2009 21:49

можно id элемента в качестве параметра передавать
p.s. не понял, почему не получилось
Цитата:

Может стоит тогда ссылки на LI и XMLHttpRequest засылать как аргументы. Тогда в this будет то, что и должно в них быть. Или наоборот: первый аргумент - ссылка на текущий экземпляр, this - ссылка на LI/XMLHttpRequest

Riim 23.04.2009 22:06

Цитата:

Сообщение от x-yuri
а это не самый распространенный путь в memory leak'и?

самый :)

Цитата:

Сообщение от x-yuri
можно id элемента в качестве параметра передавать
p.s. не понял, почему не получилось

Все получилось (у меня, по крайней мере), просто сейчас еще раз перечитал ТС и понял: нужно !вообще! без замыканий. Т. е. даже id элемента нельзя: вообще никаких аргументов.
Только event, который сам по себе крепится. У event-а есть target, который в обоих случаях будет тем же this (или undefined).
Значит, остается только прицепиться к this. Нужно просто то, что хочется засылать как аргументы прикреплять к будущему this как свойства.

Примерно так:

перед строкой
document.getElementById(id).getElementsByTagName(" li")[i].addEventListener("click", this.clickHandler, false);
добавить
document.getElementById(id).getElementsByTagName(" li")[i].currentTree = this;
и далее в Tree.prototype.clickHandler получить текущий экземпляр можно так: this.currentTree

x-yuri 23.04.2009 22:20

Цитата:

У event-а есть target который в обоих случаях будет тем же this
точно в обоих?
Цитата:

Нужно просто то, что хочется засылать как аргументы прикреплять к будущему this как свойства
а this не должен указывать на li/xmlhttprequest соответственно в этих 2х случаях?

Riim 23.04.2009 22:45

Цитата:

Сообщение от x-yuri
точно в обоих?

Не проверял, но вряд ли там будет что-то полезное в данном случае.

Цитата:

Сообщение от x-yuri
а this не должен указывать на li/xmlhttprequest соответственно в этих 2х случаях?

Он как раз на них и указывает. Т. е. нет доступа к текущему экземпляру. Вот я и предлагаю дописать его к li/xmlhttprequest.

x-yuri 23.04.2009 23:29

Цитата:

Не проверял, но вряд ли там будет что-то полезное в данном случае
[readystatechange] ie: srcElement - null, ff: target - xmlhttprequest
Цитата:

Он как раз на них и указывает. Т. е. нет доступа к текущему экземпляру. Вот я и предлагаю дописать его к li/xmlhttprequest
кстати да, я сначала подумал, что ты предлагал для обоих случаев к li this добавлять :secret:


Часовой пояс GMT +3, время: 07:38.