Autor Zpráva
pako
Profil *
Mam konstruktor Cons, ktoremu pri vytvarani instancie predavam id elementu. Do prototypu pridam funkciu, ktora pri zavolani element s tymto id prepise. Ked pridam na nejaky element tester obsluhu udalosti click s funkciou f, tak mi funkcia f hlasi ze controler nie je definovany. Urcite existuje nejaky rozumnejsi sposob ako pouzitie anonymnej funkcie. Poradi niekto ? :)
(Funkciu f nechcem definovat v konstruktori Cons)
function Cons(con) {
    this.controler = document.getElementById(con);
}

var co = new Cons('control');
var co2 = new Cons('control2');

Cons.prototype.f = function () {
    this.controler.innerHTML = 'HOTOVO';
}

function fo(x) {
     x.f.call(x);
}

document.getElementById('tester').addEventListener('click',function () {fo(co);},false);
document.getElementById('tester2').addEventListener('click',function () {fo(co2);},false);
Jan Kupka
Profil
pako:

Ahoj, nevím, jestli ti dobře rozumím, ale podle mě to jinak nejde. Pokud přidáš obsluhu události na element, tak this bude v handleru té události ukazovat na element, který tu událost spustil, případně na window (a tam žádný "controler" pochopitelně definovaný není). Pokud tedy chceš zavolat metodu objektu jako handler, musíš jí umístit do (anonymní) fce a přiřadit jí správný kontext přes call/apply (nebo volat onu metodu s bindem).
pako
Profil *
Jan Kupka:
ide o to ze takto tu obsluhu nebudem moct z elementu odstranit, co by v tomto pripade nebol problem ale niekedy v buducnosti by som nieco take mohol potrebovat a nevedel by som to spravit ;) ak funkciu f definujem v konstruktore a tam odlozim do nejakej premennej odkaz na this v momente ked sa tvori instancia tak to funguje... to ma privadza k tomu, ze ked sa to da spravit v konstruktore, nechapem preco to nie som schopny spravit definovanim v prototype...
Chamurappi
Profil
Reaguji na paka:
Proč nepoužiješ normálně document.getElementById('tester').onclick? Ten by ti tedy problém s this nevyřešil, ale zrušit ho můžeš kdykoliv. (Krom toho funguje ve všech prohlížečích, na rozdíl od addEventListener.)
pako
Profil *
Chamurappi:
s javascriptom len zacinam a docital som sa dve veci:
1. ie ma vraj problem s pamatou a je dobre odpajat udalosti
2. kvoli vykonu je dobre ked su metody ktore moze zdielat viac instancii definovane v prototype

preto som chcel vediet ci je nejaka moznost dostat do prototypu odkaz na this v momente ked sa vytvara instancia Cons a pouzit ho v prototype -> teda obist volanie funkcie f do oboru platnosti instancie Cons cez anonymnu funkciu a tym padom mat aj moznost odstranit obsluhu udalosti nielen cez .onclick = null
preca1
Profil
pako:
> s javascriptom len zacinam a docital som sa dve veci:
1. ie ma vraj problem s pamatou a je dobre odpajat udalosti
2. kvoli vykonu je dobre ked su metody ktore moze zdielat viac instancii definovane v prototype
Jen taková poznámka - tomuhle se řiká předčasná optimalizace a většinou to není dobrá věc. Lepší než řešit, že IE má možná problémy s pamětí, je tu věc napsat a vyzkoušet.
A controller se píše se dvěma l.
1Pupik1989
Profil
Teď nevím jestli jsem správně pochopil. Co má být vlastně výsledkem? Metoda f je tam správně a vše jde. Akorát ta funkce fo tam je navíc.

function Cons(con) {
    this.controler = document.getElementById(con);
};

Cons.prototype.f = function () {
    this.controler.innerHTML = 'HOTOVO';
};

var co = new Cons('control');
var co2 = new Cons('control2');
 
document.getElementById('tester').onclick = function(){
  co.f();
};
document.getElementById('tester2').onclick = function(){
  co2.f();
}
pako
Profil *
preca1:
dakujem za upozornenie, nasiel som si par clankov k teme a som zvedavy co sa dozviem.
1Pupik1989:
ciel bol, aby fungovala obsluha udalosti takto: document.getElementById('tester').onclick = co.f;
co sa da dosiahnut pridanim kodu do konstruktora
    var that = this;
    this.f  = function() {
        that.controler.innerHTML = 'HOTOVO';
    };
a vynechanim definicie f v prototype
kedze this pri volani obsluhy patri elementu tester, this.controler vo funkcii f definovanej v prototype samozrejme hlasi ze this.controler neexistuje a chcel som vediet ci to neda obist podobne ako v konstruktore ulozenim odkazu na this a jeho precitanim v Cons.prototype.f

ale ako podotkol preca1 je to asi zbytocne uvazovat pred otestovanim, ja som len cital ze tento postup je odporucany. predpokladam ze by to mohol byt problem keby som vytvaral tych instancii tisicky. kazdopadne ale zo zvedavosti by som chcel vediet ci sa to da alebo nie ;)
1Pupik1989
Profil
No šlo by na to jít z druhé strany:
Cons.prototype.addEvent = function(domEl,name){
  var that = this;
  domEl[name] = function(){
    that.f();
  };
};

co.addEvent(document.getElementById('tester'),"onclick");

nebo metodu zavolat až v anonymní funkci
document.getElementById('tester').onclick = function(){ co.f(); };

Ještě mě napadla jedna možnost:
Cons.callObject = function(obj){
  return function(){
    obj.f();
  }
};

document.getElementById('tester').onclick = Cons.callObject(co);
pako
Profil *
1Pupik1989:
vdaka za napady, otestujem.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: