ugrás a tartalomhoz

jQuery custom event: csak DOM elemhez lehet kötni?

Hodicska Gergely · 2008. Május. 12. (H), 20.28
Sziasztok!


Épp bütykölök egy kis tesztelő cuccot, ahol ha a megfigyelés beindul, akkor több elemnek egymástól függetlenül el kéne kezdeni ügyködni. Gondoltam, hogy a start gomra kattintva dobok egy saját eseményt, amire a beregisztrált listenerek reagálnak, így ha épp szeretnék hozzáadni valamit, akkor a "bootstrap" kódot nem kell módosítani, az új cucc is regisztrálja magát az eseményre.

Újabb probléma: jól látom, hogy jQueryben csak DOM elemhez lehet eseményt kötni? A fentihez nekem az lenne logikus, hogy 1-1 osztály listener metódusát regisztrálom, de egyenlőre úgy tűnik, hogy kénytelen vagyok valamilyen elemhez kötni ezt.

Így most kb. azt tudom elképzelni, hogy minden egyes "valami" az úgyis mondjuk egy DIV-ben lesz, így ehhez a DIV-hez bindoom az eseményt, és minden ilyen DIV-nek adok mondjuk egy "monitoringListener" classt, és a trigger()-nél meg ezt használom. Tényleg ennyire macerásan lehet csak?


Üdv,
Felhő
 
1

Bind

blast · 2008. Május. 13. (K), 04.43
helló,

.click() helyett: .bind( type, [data], fn ) így lehet több eseményt hozzácsatolni, mondjuk click-re. pl, $(this).bind("click", function(e){ a++; });

Ugyan erre lesz szükséged egyéni esemény regisztrálásnál. pl.:

$(this).bind("timeout,function() {
$sutff.calc( $(this).removeClass("timer").children("input").val() );
})

$(this).trigger('timeout');

Hasznos lehet még a .data ,
ami megoldhatja a másik topicban megfogalmazott this problémád.
2

jelen probléma szempontjából lényegtelen

Hodicska Gergely · 2008. Május. 13. (K), 06.54
A probléma szempontjából ez lényegtelen, a click csak egy rövídítés, egy felparaméterezett bind. A bajom, hogy saját eseményt csak DOM elemhez tudok kötni (legalábbis úgy tűnik), nem tudom azt mondani, hogy ha ez az esemény bekövetkezik, akkor mondjuk ez a függvény hívódjon meg.

Hasznos lehet még a .data
Szerintem az ottani megoldás lényegesen szebb és transzparensebb, mintha beletenném a data tömbbe a this-t, majd mindig előkaparnám. Kb. prototype bindAsEventlistener-e is hasonló lehet, csak csodálkoztam, hogy egy jQuery-ben ezt "kézzel" kell az embernek megcsinálni, nincs rá kész megoldás (azért ez egy elég ismert probléma, és szerintem manapság azért nem olyan egyedi, hogy osztályokat használjon az ember).


Üdv,
Felhő
5

jQuery, pici, és az is marad.

blast · 2008. Május. 13. (K), 18.02
A jQuery egyik lényeges szempontja hogy nagyon kicsi, biztosan nem lesz benne olyan funkciók tömkelege, mint az Extben.
Viszont könnyedén kiegészíthető. A probléma nem egyedi, mint ahogy mondtad, nem csak Te dolgozol object.prtototypal. Éppen ezért vannak apró pluginok, mint pl: Bindo, Distill , FastTrigger ,
és ha saját megoldásodat érdemesnek tartod publikálni, nem áll semmiből. A jQueryből rengeteg alapvetőnek gondolt funkció hiányzik, és hiányozni is fog. Tehát nem azoknak van, akik nem akarnak kiegészítést írni hozzá. Inkább azoknak akik jobban szeretnek valamit otthonosan felépíteni, sok felesleges sallang nélkül. (ezért van ekkora tábora.)

Éppen ezért nem állja meg a helyét az, hogy a jQuery itt-ott lassú. Összességében egy komplex webalkalmazásban mindig gyorsabb lesz, mint egy Ext. Amiben effektíve több programozást igényel az, hogy kitakarítsd a szemetet. És ez annak köszönhető, hogy sokszor ilyen alapvetések nem kerülnek bele.

Persze ezt nem te állítottad, csak olvastam pár commentben ilyesmit.

Egyébként a problémádat az új jQuery releaseben valamelyest implementálni fogják. Nézd meg a blogot!
3

Extjs observable

Jano · 2008. Május. 13. (K), 13.18
Nem tudom segít-e, de ExtJS-ben van egy Observable osztály, amiből származtatott osztályok képesek eseményeket generálni és azt mások megfigyelhetik.
4

workaround

Hodicska Gergely · 2008. Május. 13. (K), 14.37
Végülis sikerült most egész szépen lekezelni a már kérdésben is felvetett lehetőséggel, ez amolyan játszási projekt, szóval elég volt. Nyilván egy bonyolultabb valamit nem szeretnék ilyen módon összedrótozni. Amiről tudom, hogy nagyon szépen meg van oldva, az a dojo eseménykezelése, ott olyan szinten meg van csinálva, hogy jó formás aspektus orientáltan is lehet programozni. Meg azy hiszem, hogy YUI-ban is voltak custom eventek, de nem használtam, csak annó ódákat zengtek az eseménykezeléséről.

Kb. ez lett a vége most:
<div><b>XY gateway status</b><span id="xyGatewayMonitor" class="monitoringListener"></span></div>
<div><b>XY table status</b><span id="xyTableMonitor" class="monitoringListener"></span></div>
<div><b>xyz table status</b><span id="xzyTableMonitor" class="monitoringListener"></span></div>
JavaScript rész:
(
	function ($) {
		$.delegate = function (scope, func) {
			var _scope = scope;
			return function () {func.apply(_scope, arguments);}
		}
		$.log = function (message) {
			if ( window.console ) {
				window.console.debug(message);
			}
		}
	}
)(jQuery);


$(document).ready(function () {
	monitoring = new Monitoring();
});


var Monitoring = function() {
	....
	this.isRunning   = false;
	this.refreshTime = 2000;
	....

	this.xyGatewayMonitor = new Monitor(this, 'xyGatewayMonitor', 'getXyGatewayStatus');
	this.xyTableMonitor   = new Monitor(this, 'xyTableMonitor', 'getXyTableStatus');
	this.xzyTableMonitor  = new Monitor(this, 'xyzTableMonitor', 'getXyTableStatus');
	....
}
Monitoring.prototype = {
	/**
	 * Elinditja vagy megallitja a monitorozast.
	 */
	toggleMonitoring: function(event) {
		...

		$(event.target).html(this.isRunning ? 'Start monitoring' : 'Stop monitoring');
		this.isRunning = !this.isRunning;
		// Ezzel az esemennyel jelezzuk a monitorozasban resztvevo minden elemnek, hogy kapcsolja be/ki magat.
		$('.monitoringListener').trigger('toggleMonitoring');
		....
	},
...
}
var Monitor = function (monitoring, idOfTheDisplayTag, getStatusAction) {
	this.monitoring = monitoring;
	this.idOfTheDisplayTag = idOfTheDisplayTag;
	this.getStatusAction = getStatusAction;
	this.getStatusTimer = null;

	$('#'+this.idOfTheDisplayTag).bind('toggleMonitoring', $.delegate(this, this.toggleMonitoring));
	...
}