Domanda

Ho scritto app guidate dagli eventi in C ++ usando i pulsanti MFC per GUI e utilizzo eventi HTML come onmousedown per attivare Javascript in una pagina Web. L'idea della programmazione guidata dagli eventi è intuitiva quando si utilizza l'interfaccia e gli eventi sono codificati.

So come usare un puntatore a funzione in C, e vedo come Windows li usa per eseguire un loop di eventi. Posso scrivere codice per chiamare in modo dinamico una funzione diversa.

Il mio problema è passare dal tempo di compilazione al runtime. Sto parlando qualsiasi lingua qui, ma se hai bisogno di una lingua, scegli Javascript o PHP come li uso più in questi giorni. Non ho la minima idea di come potrei usare il mio oggetto evento per fare qualcosa. Non è solo un concetto che ottengo. E dal momento che non li uso, non so quale potrebbe essere il loro uso pratico.

Ad esempio, suppongo che se volessi creare un gioco a turni personalizzato, che avrei potuto usare gli oggetti evento per rappresentare un effetto di qualche abilità di un pezzo di gioco che deve solo "accadere".

Qualcuno può darmi un semplice uso di eventi personalizzati? O situazioni in cui è utile o pratico? Dipende in gran parte dalla lingua e dall'ambiente e da come vengono gestiti gli eventi? Una risposta Javascript sarebbe buona, ma ho letto molte lingue.

Mi dispiace, sono solo carente in questo senso e ho bisogno di approfondimenti pratici, avanzati (intermedi?). È come un puntatore in C. I " get " puntatori e come sono tuoi amici. Ma c'è stato un tempo in cui non l'ho fatto, e molte persone che conosco ancora non lo fanno. È semplice quando lo ottieni, non riesco proprio a ricevere eventi dinamici e personalizzati in questo modo.

È stato utile?

Soluzione

Quando parliamo di programmazione orientata agli eventi, di solito parliamo di una o più implementazioni di pattern di progettazione dell'osservatore . E un obiettivo del modello di progettazione dell'osservatore è quello di raggiungere accoppiamento lento tra oggetti.

Questo probabilmente non significa molto senza un buon esempio, e ce ne sono sicuramente molti buoni là fuori; Dubito che il mio sarà il migliore, ma lo farò comunque. Immagina due oggetti. Un oggetto vuole sapere quando succede qualcosa con l'altro oggetto, quindi può fare qualcosa da solo - forse il cane di famiglia, Rover, vuole salutare papà alla porta quando torna a casa dal lavoro. Ci sono un paio di modi in cui potresti programmare quello scenario, giusto?

  • Assicurati che papà abbia un riferimento a Rover e, quando torna a casa, chiama il metodo greetDatAtTheDoor () di Rover, oppure

  • Dai a Rover un riferimento a papà, ascolta l'evento onArriveHome di papà, e quando spara, chiama greetDadAtTheDoor () internamente.

In superficie, potrebbe non sembrare che ci sia molta differenza tra i due, ma in realtà papà ha una parte dell'implementazione di Rover in lui; se l'implementazione di Rover dovesse cambiare per qualche motivo, dovremmo apportare modifiche in due punti: una volta a Rover e poi di nuovo a papà. Non è un grosso problema, forse, ma comunque non ideale.

Ora immagina che anche la mamma voglia salutare papà. E il gatto, il signor Bigglesworth, a cui non piace molto papà, vuole assicurarsi che non ci sia, quindi preferisce uscire. E un vicino di casa, Joe, vuole sapere quando papà torna a casa, quindi può infastidirlo per quei venti dollari che papà gli deve. Come consideriamo tutti quegli scenari e quelli aggiuntivi che inevitabilmente affioreranno? Inserendo riferimenti al metodo greetHusband () della mamma, al metodo getOutNow () del gatto, al metodo greetDadAtTheDoor () del cane e al metodo goGetMyMoney () di Joe nella definizione di classe di papà, si rovinerebbe rapidamente per papà - e senza una buona ragione, dal momento che tutto Papà ha davvero bisogno di fare, se stesso, è tornato a casa. La mamma, il cane, il gatto e il vicino vogliono solo essere informati quando ciò accade, in modo che possano fare qualunque cosa le loro implementazioni interne richiedano.

Le lingue gestiscono le specifiche di queste cose in diversi modi, ma come vedrai quando inizi a cercare su Google, lo schema di solito implica che ci sia una matrice, o una struttura simile a una matrice, sull'evento "dispatcher" (in questo caso, papà, ovvero l'oggetto a cui tutti gli altri sono interessati) e gli "abbonati" (ad es. mamma, il gatto, Rover e Joe) tutto " registrati " chiamando un metodo esposto pubblicamente sul dispatcher e passando riferimenti a se stessi - riferimenti che finiscono, in qualche forma, nella matrice di papà di "abbonati". Quindi, quando papà torna a casa, "spedisce" un evento - il " I'm home! " l'evento, diciamo - che è essenzialmente una funzione che circola su ciascuno dei suoi abbonati e li invoca con un loro metodo accessibile pubblicamente - solo che è un metodo il cui nome papà non conosce, non deve sapere, perché l'ascoltatore lo ha fornito quando lo ha passato.

Dal momento che mi capita di scrivere codice per lo più ActionScript in questi giorni, ecco come potrebbe apparire nel mio mondo - diciamo, come dichiarato dalla mia classe Mom:

var dad:Dad = new Dad();
dad.addEventListener(DadEvent.ARRIVED_HOME, greetHusbandAtDoor);

private function greetHusbandAtDoor(event:DadEvent):void
{
   // Go greet my husband
}

In papà, quindi, tutto quello che devo fare, quando torno a casa, è:

dispatchEvent(new DadEvent(DadEvent.ARRIVED_HOME));

... e poiché Flash gestisce i dettagli di invio e notifica degli eventi per me (di nuovo, tutti lo fanno in modo leggermente diverso, ma internamente, Flash segue il modello concettuale che ho descritto), mio ??padre torna a casa e ciascuno fa un membro della famiglia

Altri suggerimenti

In una lingua compilata, scrivi il tuo ciclo di eventi. In un linguaggio di runtime, è già implementato dall'ambiente host e il programmatore ottiene solo un'interfaccia astratta nel sistema degli eventi. Non vedi mai il ciclo degli eventi.

Ci sono due aspetti per costruire funzionalità con eventi. Il primo è definire le condizioni in base alle quali verrà generato un evento. In javascript in un browser, non esiste una sola "mousedown" evento. Ce n'è infatti uno per ogni elemento della pagina. In questo caso, la condizione per l'attivazione di uno di essi si basa sia sulla posizione del cursore del mouse, sia sul fatto che il pulsante del mouse sia appena passato dallo stato su allo stato giù. Questa condizione può causare l'attivazione di più eventi. (Nel browser, c'è qualcosa chiamato evento "bubbling" che è correlato a questo. Ma qui è fuori portata).

L'altro aspetto è il gestore eventi. Un evento accade indipendentemente dal fatto che ci sia o meno un gestore. Fornire il gestore dipende da te. In JavaScript, le funzioni sono valori di prima classe. Vengono definiti in fase di esecuzione, non in fase di compilazione, quindi non sono necessari puntatori o tabelle di salto. Si crea una nuova funzione in fase di esecuzione e la si assegna a una proprietà speciale che l'ambiente host cerca quando viene generato un determinato evento.

quindi, in caso di overflow dello stack, ci sarà un gestore di eventi su ciascuna delle frecce in giù "quotclick" eventi, che trasforma la freccia in rosso, decrementa un numero, controlla qualche altra variabile e mostra condizionalmente una notifica. Quindi quando il gestore ritorna, restituisce il controllo del thread al browser e alleluia l'utente può interagire nuovamente con il browser. (tutte le interazioni cessano mentre viene gestito un evento, quindi è meglio renderlo veloce). Ecco un esempio usando la libreria jquery.

jQuery("a .downarrow")
.click(function(e){ e.target.style.color="red" /* ... do other things */ });

o in javascript non elaborato (versione 1.6) potrebbe essere

Array.prototype.slice.apply(document.getElementsByTagName("a"))
.filter(function(o){ return !!(/downarrow/).exec(o.className)})
.forEach(function(o){ 
    o.onclick= function(e){ 
        e.target.style.color="red" /* ...do other things * / 
    }
 });

È davvero così semplice. Il motivo principale per cui dovresti fare qualcosa del genere è che consente l'interazione asincrona. Un'applicazione gui non procede in linea retta, passo dopo passo. Deve rispondere dinamicamente all'input dell'utente. Gli eventi sono un modo per simulare l'aspetto di un'applicazione multithread. Può sembrare all'utente che molte cose accadano simultaneamente senza interromperle.

È possibile utilizzare una libreria per definire un evento personalizzato. Questo potrebbe forse codificare qualche evento specifico del dominio. Ad esempio: hai una partita a scacchi che sta pensando alla sua prossima mossa. il processo di ricerca della mossa si esaurisce. La partita a scacchi potrebbe sparare un "onComputerMove" evento. È possibile gestire quell'evento con una funzione che acquisisce le specifiche per lo spostamento e aggiorna la rappresentazione visiva della scacchiera, apre un messaggio per l'utente ed esce. Quindi quando il giocatore si sposta puoi sparare un "onPlayerMove" evento, che fa più o meno la stessa cosa.

La cosa più meravigliosa degli eventi è la riduzione dell'accoppiamento esplicito bidirezionale tra due moduli o classi.

Quindi diciamo che ho due lezioni: Baby and Mommy


Senza eventi, vedo approssimativamente due metodi per consentire a una mamma di nutrire un bambino:

  • la mamma chiama il metodo baby.pokeBelly () sul bambino ogni mezz'ora per sapere se devi chiamare baby.fillWith (latte) .
    Il problema è che il thread della mamma deve aspettare tutto il giorno dopo il bambino in un ciclo di tempo
  • Baby conosce la sua mamma associata e chiama un metodo mommy.feed (me) , che a sua volta chiama baby.fillWith (latte) .
    Il problema è che chiedere a un semplice bambino di chiedere alla mamma giusta di riempirsi la pancia.
    I bambini non lo fanno perché dovrebbero rimanere semplici.

Con gli eventi, potresti associare un Mommy.OnBabyCries (baby) all'evento baby.Cry del suo bambino:

void Mommy.OnBabyCries(baby) {
    baby.fillWith(milk)
}

Dopo questo, se il bambino vuole mangiare, tutto ciò che deve fare è aumentare il suo evento Cry.

La logica rimane nella mamma, o anche più tardi in qualsiasi babysitter, e il bambino rimane felice, senza doversi preoccupare.

Non so se capisco perfettamente la tua domanda, ma una classe con un evento è proprio come una GUI con un pulsante. Pensaci come un omoncolo ... All'interno di ogni classe con un evento c'è una piccola persona con un pulsante virtuale da premere. Non sa cosa farà il pulsante, ma sa quando premerlo. Ora pensa a una classe correlata con un'altra piccola persona al suo interno. Quella persona sa che quando sente un messaggio che è stato premuto un pulsante, dovrebbe fare qualcosa.

Ogni volta che vuoi che il secondo ragazzo sappia qualcosa del primo ragazzo, colleghi il centralino tra la prima e la seconda classe (Iscriviti all'evento). Quando il primo ragazzo preme il pulsante (attiva l'evento), il secondo fa qualsiasi cosa sappia che dovrebbe fare ...

Non so se questo aiuta o sto solo facendo un viaggio acido pensando a piccole persone nei miei programmi ...

In StackOverflow , quando voti in basso, la tua reputazione diminuisce e la tua freccia in giù diventa rossa.

Di solito, scrivi un singolo onclick , aggiorni tutti gli elementi in esso e cerchi di non dimenticare di cambiarlo ogni volta che cambia il layout della pagina.

Invece, puoi dichiarare l'evento onVoteDown , attivarlo in onclick e iscriverti a questo evento:

  • la tua reputazione div
  • la tua freccia img
  • il tuo XmlHTTPRequest che invia il tuo voto al server.

Non sono del tutto sicuro del tipo di risposta che stai cercando, quindi mi scuso se non è qualcosa di simile. ;)


Per personalizzato , vuoi dire azioni personalizzate , trigger personalizzati o veramente eventi personalizzati ?

Ad esempio: una azione personalizzata risponderebbe a un evento predefinito (ad esempio, un clic del mouse), un trigger personalizzato sarebbe falso un clic del mouse tramite script e un evento personalizzato sarebbe un ascoltatore che non è definito dalla lingua o non è prontamente disponibile.

Se stai cercando eventi personalizzati , non posso davvero aiutarti. Tuttavia, non credo che ci sia molto supporto per loro in JavaScript.


Per definire un Azione ...

Gli eventi vengono normalmente stabiliti tramite proprietà predefinite di un oggetto, ad esempio window.onload . Per impostazione predefinita, sono tutti uguali a undefined o null . Quindi, per metterli in pratica, devi impostarli sul valore di una funzione.

Puoi utilizzare un " anonimo " Funzione:

window.onload = function (eventObject) {
    /* ... */
};

Oppure impostali su un riferimento di funzione (non uguale, ma simile a un puntatore):

function handleOnload(eventObject) {
    /* ... */
}

window.onload = handleOnload; /* note the lack of parenthesis */

Quando viene attivato l'evento, viene chiamata la funzione. Pertanto, in entrambe le impostazioni, al termine del caricamento della pagina, verrà eseguito il codice inserito anziché / * ... * / .

Sono disponibili anche metodi più formali per la creazione di eventi. W3C definisce addEventListener mentre IE utilizza attachEvent . Ulteriori informazioni .

Sono disponibili molti riferimenti per l'apprendimento dell'elenco degli eventi disponibili. Ecco 2 che dovrebbero darti una buona base:


Il browser di solito gestisce l'attivazione di eventi, sia per eventi del browser ( onload ) o eventi utente ( onclick ). La proprietà e la funzione sono destinate a rispondere.

Attivazione il tuo evento non è la cosa più semplice da realizzare. Per definire completamente un oggetto Event è necessario un po 'di lavoro e varia tra i browser .

Tuttavia, se non hai bisogno dell'oggetto Event , puoi semplicemente chiamare l'evento:

window.onload();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top