Eventi personalizzati in CLASSE

Ho bisogno di lanciare eventi personalizzati dalla CLASSE. So che per fare questo con oggetti DOM e jquery, utilizzando triggerHandler, come $(oggetto)..triggerHandler(“inputChange”, {param:X});
Il problema è che quando provo questo con una Classe, come questo:

    var MyClass = (function(){

        var static_var = 1;

        var MyClass = function () {

            var privateVar;
            var privateFn = function(){ alert('Im private!'); };

            this.someProperty = 5;
            this.someFunction = function () {
                alert('Im public!');
            };
            this.say = function() {
                alert('Num ' + this.someProperty);
                $(this).triggerHandler("eventCustom");
            }
            this.alter = function() {
                this.someProperty ++;
            }
        };

        return MyClass;

    })();

    TheClass = new MyClass();

    $(TheClass).on('eventCustom', function() {
        alert('Event!');
    });

    TheClass.say();

Questo non lanciare avvisi o errori, ma gli eventi ascoltatore non funziona (o non viene inviato nessun evento). Penso jQuery evento di sistema non funziona, non oggetto DOM, corretto?

Qualsiasi altro modo (ho bisogno di eventi, non richiamate per il mio caso specifico) per lanciare gli eventi?

Grazie mille!

InformationsquelleAutor Zenth | 2013-06-18



2 Replies
  1. 9

    La vostra comprensione di come funziona javascript è limitato, in quanto si sta avvicinando dalla tradizione OOP punto di vista. Date un’occhiata a questo violino http://jsfiddle.net/9pCmh/ & vedrete che si può effettivamente passare le funzioni di variabili per altre funzioni. Non ci sono classi in javascript, solo le funzioni che possono essere le chiusure che può essere fatta per emulare le lezioni tradizionali:

    var MyClass = (function(){
    
        var static_var = 1;
    
        var MyClass = function ( callback ) {
    
            var privateVar;
            var privateFn = function(){ alert('Im private!'); };
    
            this.someProperty = 5;
            this.someFunction = function () {
                alert('Im public!');
            };
            this.say = function() {
                alert('Num ' + this.someProperty);
                callback();
            }
            this.alter = function() {
                this.someProperty ++;
            }
        };
    
        return MyClass;
    
    })();
    
    TheClass = new MyClass(function() {
        alert('Event!');
    });
    
    TheClass.say();

    In alternativa, è possibile creare una funzione di “classe” per configurare la funzione di callback/trigger invece passando al costruttore.

    Dare un’occhiata a questo come un punto di partenza per il tuo ulteriore lettura su questo concetto… Come JavaScript chiusure di lavoro?

    Modifica

    Per placare quei critici che cercano un eventQueue qui è un aggiornamento jsfiddle 🙂

    http://jsfiddle.net/Qxtnd/9/

    var events = new function() {
      var _triggers = {};
    
      this.on = function(event,callback) {
          if(!_triggers[event])
              _triggers[event] = [];
          _triggers[event].push( callback );
        }
    
      this.triggerHandler = function(event,params) {
          if( _triggers[event] ) {
              for( i in _triggers[event] )
                  _triggers[event][i](params);
          }
      }
    };
    
    var MyClass = (function(){
    
          var MyClass = function () {
    
              this.say = function() {
                  alert('Num ' + this.someProperty);
                  events.triggerHandler('eventCustom');
              }
          };
    
          return MyClass;
    
      })();
    
      TheClass = new MyClass();
    
      events.on('eventCustom', function() {
          alert('Event!');
      });
      events.on('eventCustom', function() {
          alert('Another Event!');
      });
    
      TheClass.say();
    • Anche se questo potrebbe funzionare, il sistema di eventi offerti da jQuery è superiore di gran lunga. Davvero non rispondere alla domanda IMO, OP esplicitamente dichiarato “in altro modo (ho bisogno di eventi, non richiamate per il mio caso specifico) per lanciare gli eventi?”. E loro sanno già sul passaggio di funzioni alle altre funzioni, che stanno facendo questo quando si chiama .on.
    • Si prega di spiegare a me come jQuery eventi sono superiori a javascript chiusure/callback? jQuery eventi di callback. In sostanza un evento è un callback, in javascript, l’unica differenza è che si può mettere in coda di eventi che si può facilmente fare con javascript richiamate. L’OP la comprensione di ciò che un evento in javascript è viziata perché sta pensando in OOP termini. So che mi è venuto da C++ & utilizzare PHP avevano una grande curva di apprendimento.
    • Nel tuo esempio si può passare solo un callback a un’istanza, al momento della sua creazione. Con un evento vero e proprio sistema, è possibile associare più diversi gestori di eventi in qualsiasi momento. È proprio quello che intendevo. Del corso di “callback” è solo un termine popolare una funzione passati a un’altra funzione.
    • ecco fatto, il mio problema è che ho bisogno di “legarsi” alcune “azioni” per lo stesso evento, in differenti parti e “momenti” nel mio codice. Richiamata la sua non e ‘ una soluzione per questo caso. Ho bisogno di attivare eventi.
    • Guarda l’edit, ho incluso un esempio di un evento coda
    • PS. Non ho inserito alcun controllo di errore valido per le richiamate etc. Questo si può fare come si richiede.
    • jajaja questa è una trappola, è un “falso-evento” sistema di funzioni di controllo, ma.. la sua risolvere il mio problema 😛 mi fa collegare in qualche modo un evento di classe MyClass per l’uso come “TheClass.on(‘eventname’)”, “TheClass.off(‘eventname’)”, ma funziona “male” non posso usare jquery evento di default del sistema in una classe. Grazie per la soluzione.
    • solo una correzione: questo.triggerHandler = function(event, params) { var persone a mobilità ridotta = params || {} ; if( _triggers[evento] ) { for( i in _triggers[evento] ) _triggers[evento][i](prm); } }
    • Whoops… buon punto… aggiornato! Si potrebbe anche usare _triggers[evento][i].applicare( questo Array.prototipo.fetta.chiamata(argomenti, 1) ); se si voleva passare più parametri.
    • NP io passo i parametri sempre oggetto di {}. Ora ho un altro problema.. ho dichiarato triggerHandler(), questo.on() e questo.off(), tutto il lavoro ok, ma ho bisogno _triggers[evento][i](prm); il 1º parametro devono essere della STESSA classe (come la “e” oggetto in eventi regolari), im cercare di rendere in qualche modo, ma solo opere private var come il var che = questo, e inviare come _triggers[evento][i](che, persone a mobilità ridotta); ma questa restituire l’oggetto al momento iniziale, NON il grilletto momento (vars in oggetto null, non con i valori) qualsiasi idea di tornare in classe? Grazie
    • cerchiamo di continuare questa discussione in chat
    • Sembra jsfiddle è oudated, ‘eventCustom’ è codificata in triggerHandler

  2. 1

    Ho scritto un ES6 classe di evento per oggi in meno di 100 righe di codice senza l’utilizzo di JQuery. Se non si desidera utilizzare DOM-eventi puoi estendere la tua classe, che dovrebbe fare con gli Eventi.

    Per l’ascolto di eventi, è possibile utilizzare , una volta, onReady, onceReady. È eseguire il callbackfunction ogni volta che l’etichetta è di trigger. Una volta solo una volta. Il “pronto”-funzioni di eseguire il callback, se l’etichetta era stata già triggerd prima.

    Per l’attivazione di un evento, utilizzare un trigger. Per rimuovere un eventhandler, uso off.

    Spero che l’esempio rende evidente:

    JS:

    class ClassEventsES6 {
                    constructor() {
                        this.listeners = new Map();
                        this.onceListeners = new Map();
                        this.triggerdLabels = new Map();
                    }
    
                    //help-function for onReady and onceReady
                    //the callbackfunction will execute, 
                    //if the label has already been triggerd with the last called parameters
                    _fCheckPast(label, callback) {
                        if (this.triggerdLabels.has(label)) {
                            callback(this.triggerdLabels.get(label));
                            return true;
                        } else {
                            return false;
                        }
                    }
    
                    //execute the callback everytime the label is trigger
                    on(label, callback, checkPast = false) {
                        this.listeners.has(label) || this.listeners.set(label, []);
                        this.listeners.get(label).push(callback);
                        if (checkPast)
                            this._fCheckPast(label, callback);
                    }
    
                    //execute the callback everytime the label is trigger
                    //check if the label had been already called 
                    //and if so excute the callback immediately
                    onReady(label, callback) {
                        this.on(label, callback, true);
                    }
    
                    //execute the callback onetime the label is trigger
                    once(label, callback, checkPast = false) {
                        this.onceListeners.has(label) || this.onceListeners.set(label, []);
                        if (!(checkPast && this._fCheckPast(label, callback))) {
                            //label wurde nocht nicht aufgerufen und 
                            //der callback in _fCheckPast nicht ausgeführt
                            this.onceListeners.get(label).push(callback);
                    }
                    }
                    //execute the callback onetime the label is trigger
                    //or execute the callback if the label had been called already
                    onceReady(label, callback) {
                        this.once(label, callback, true);
                    }
    
                    //remove the callback for a label
                    off(label, callback = true) {
                        if (callback === true) {
                            //remove listeners for all callbackfunctions
                            this.listeners.delete(label);
                            this.onceListeners.delete(label);
                        } else {
                            //remove listeners only with match callbackfunctions
                            let _off = (inListener) => {
                                let listeners = inListener.get(label);
                                if (listeners) {
                                    inListener.set(label, listeners.filter((value) => !(value === callback)));
                                }
                            };
                            _off(this.listeners);
                            _off(this.onceListeners);
                    }
                    }
    
                    //trigger the event with the label 
                    trigger(label, ...args) {
                        let res = false;
                        this.triggerdLabels.set(label, ...args); //save all triggerd labels for onready and onceready
                        let _trigger = (inListener, label, ...args) => {
                            let listeners = inListener.get(label);
                            if (listeners && listeners.length) {
                                listeners.forEach((listener) => {
                                    listener(...args);
                                });
                                res = true;
                            }
                        };
                        _trigger(this.onceListeners, label, ...args);
                        _trigger(this.listeners, label, ...args);
                        this.onceListeners.delete(label); //callback for once executed, so delete it.
                        return res;
                    }
                }
                
    //+++ here starts the example +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    class TestClassEvents extends ClassEventsES6 {
         constructor() {
            super();
            this.once('sayHallo', this.fStartToTalk);
            this.on('sayHallo', this.fSayHallo);
         }
    
         fStartToTalk() {
             console.log('I start to talk... ');
         }
    
         fSayHallo(name = 'Nobody') {
            console.log('Hallo ' + name);
         }
    }
    
    let testClassEvents = new TestClassEvents();
    
    testClassEvents.trigger('sayHallo', 'Tony');
    testClassEvents.trigger('sayHallo', 'Tim');
    
    testClassEvents.onReady('sayHallo', e => console.log('I already said hello to ' + e));
    testClassEvents.trigger('sayHallo', 'Angie');
    testClassEvents.off('sayHallo');
    testClassEvents.trigger('sayHallo', 'Peter');
    console.log('I dont say hallo to Peter, because the event is off!')

Lascia un commento