Объектная модель

 
0
 
JavaScript
ava
maxkazar | 03.12.2004, 12:29
Необходимо в объекте использовать задержку(таймер) window.setTimeout().
Например:

function Test() {
this.Action = fnAction
this.SetTimer = fnSetTimer
this.Name = "Test"

function fnAction() {
alert(this.Test)
}

function fnSetTimer() {
setTimerout("this.Action()",1000)
}

}

var T = new Test()
T.SetTimer()



Вот так бы хотелось в идеале....но к сожалению так не получится(. Т.к. вызов функции таймера (в примере this.Action() ) происходит в конетксте основного объекта (если я не ошибаюсь это будет объект window). Соответсвенно возникнет ошибка!. А как же тогда быть....как поставить таймер в объекте. Как сделать чтоб в обработчике таймера можно было использовать свойтва и методы самого объекта....

Мне в голову приходит только один способ....где-то надо хранить имя объекта (в примере T) а потом уже в обработчике получать ссылку на имя....но это полный геморой (очень далеко от идела!)
Kommentare (4)
ava
Sardar | 03.12.2004, 14:58 #
maxkazar да это проблема, которая и меня порой достает...
window.setTimeout всегда исполняет функцию в контексте window. Я писал два решения, первое прописать всем функциям ссылку на обéкт:

function myObj(n) {
this.test=n;

this.bla=function() {
  alert(arguments.callee.target.test); //берем переменную по ссылке на обьект
};
this.bla.target=this; //ссылка на обьект

this.timetest=function() {
   window.setTimeout(this.bla,1000); //ставим обычный таймер
}
}

var m=new myObj(34);
m.timetest();
var m=new myObj(100);
m.timetest();

Недаостаток что нужно всегда определять функции в конструкторе, что бы у каждого обьекта был свой обьект функция держущая ссылку на обьект target. Также ссылка arguments.callee по моему не существуетв ИЕ5.0

Можно завести регистр обьектов, в который будем складывать всех кто обратился на паузу:
function myObj(n) {
this.test=n;
this.bla=function() {alert(this.test);};

this.timetest2=function() {
  window.setTimerout(this, "bla", 1000);
}
}

setTimerout.targets={};
function setTimerout(obj, func, time) {
 var uname="~" + Math.random(); //имя должно быть уникальным, сделал по быстрому, перепиши
 setTimerout.targets[uname]={tg:obj,fn:func};
 window.setTimeout("runTimerout('"+uname+"');", time); //вызываем нашь обработчик с ИД обьекта
}
function runTimerout(id) {
 if(typeof(setTimerout.targets[id])=="object") {
   var r=setTimerout.targets[id];
   delete setTimerout.targets[id];
   r.tg[r.fn](); //так будет работать везде
//    r.fn.call(r.tg); //если передавать не имя а функцию, но так не будет работать в ИЕ5.0
 }
}


var m=new myObj(34);
m.timetest2();
var m=new myObj(100);
m.timetest2();


Можно еще извратится, главное не уйти слишком далеко smile
ava
maxkazar | 03.12.2004, 15:18 #
Вот жешь....все гениально и просто, как это я сам не догадался... Просто в самом объекте надо хранить сылку на сам объект!....это вполне нормально....я данный подход использовал и раньше вот только здесь не попробывал))
ava
Се ля ви | 03.12.2004, 20:57 #
Господа, а почему бы не передавать ссылку на объект как параметр функции? Это конечно тоже кривовато, но всё-таки красифше и универсальней:

m.Action(m);

Разве не меньшее из зол?
ava
Sardar | 04.12.2004, 00:42 #
Цитата
Разве не меньшее из зол?

И так тоже будет работать, просто выглядеит ну совсем не как ООП... smile
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
advanced
Absenden