not example change javascript object cordova addeventlistener

javascript - example - addeventlistener typescript



addEventListener en objeto personalizado (9)

Creo que puedes usar Object $ Deferred y promesas. Te dejará hacer algo como esto:

Apilado: vincula múltiples manejadores en cualquier lugar de la aplicación al mismo evento de promesa.

var request = $.ajax(url); request.done(function () { console.log(''Request completed''); });

// En algún otro lugar de la aplicación

request.done(function (retrievedData) { $(''#contentPlaceholder'').html(retrievedData); });

Tareas paralelas: hacer múltiples promesas para devolver una promesa que alerta de su finalización mutua.

$.when(taskOne, taskTwo).done(function () { console.log(''taskOne and taskTwo are finished''); });

Tareas secuenciales: ejecutar tareas en orden secuencial.

var step1, step2, url; url = ''http://fiddle.jshell.net''; step1 = $.ajax(url); step2 = step1.then( function (data) { var def = new $.Deferred(); setTimeout(function () { console.log(''Request completed''); def.resolve(); },2000); return def.promise(); }, function (err) { console.log(''Step1 failed: Ajax request''); } ); step2.done(function () { console.log(''Sequence completed'') setTimeout("console.log(''end'')",1000); });

Fuente aquí: http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt2-practical-use

Creé un objeto que tiene varios métodos. Algunos de estos métodos son asincrónicos y, por lo tanto, quiero usar eventos para poder realizar acciones cuando se realizan los métodos. Para hacer esto intenté agregar el addEventListener al objeto.

jsfiddle

var iSubmit = { addEventListener: document.addEventListener || document.attachEvent, dispatchEvent: document.dispatchEvent, fireEvent: document.fireEvent, //the method below is added for completeness, but is not causing the problem. test: function(memo) { var name = "test"; var event; if (document.createEvent) { event = document.createEvent("HTMLEvents"); event.initEvent(name, true, true); } else { event = document.createEventObject(); event.eventType = name; } event.eventName = name; event.memo = memo || { }; if (document.createEvent) { try { document.dispatchEvent(event); } catch (ex) { iAlert.debug(ex, ''iPushError''); } } else { document.fireEvent("on" + event.eventType, event); } } } iSubmit.addEventListener("test", function(e) { console.log(e); }, false); //This call is added to have a complete test. The errors is already triggered with the line before this one. iSubmit.test();

Esto devolverá un error: Failed to add eventlisterens: TypeError: ''addEventListener'' called on an object that does not implement interface EventTarget."

Ahora este código se usará en una aplicación de phonegap y cuando lo haga, está funcionando en android / ios. Sin embargo, durante las pruebas, estaría bien si pudiera hacer que funcione en al menos un navegador.

PD> Sé que podría habilitar el burbujeo y luego escuchar la raíz del documento, pero me gustaría tener solo un poco de OOP donde cada objeto pueda funcionar por sí mismo.


Este artículo explica cómo crear eventos personalizados: http://www.sitepoint.com/javascript-custom-events/

Aquí hay un ejemplo:

crea el evento -

var event = new CustomEvent( "newMessage", { detail: { message: "Hello World!", time: new Date(), }, bubbles: true, cancelable: true } );

asigna el evento a algo

document.getElementById("msgbox").dispatchEvent(event);

suscribirse al evento -

document.addEventListener("newMessage", newMessageHandler, false);


Hay dos problemas

Primero, el método iSubmit.addEventListener() es en realidad un método en la interfaz DOM de EventTarget :

Estos están destinados para su uso solo en elementos DOM. Al agregarlo al objeto iSubmit como método, lo está llamando a un objeto que no es un EventTarget . Esta es la razón por la cual Chrome arroja un Uncaught TypeError: Illegal invocation error de Uncaught TypeError: Illegal invocation JavaScript Uncaught TypeError: Illegal invocation .

El primer problema es crítico, pero si pudiera usar EventTarget#addEventListener() su código no funcionaría porque el evento se está agregando a iSubmit pero enviado desde el document . En general, los métodos del mismo objeto deben utilizarse al adjuntar escuchas de eventos y despachar eventos (a menos que esté utilizando eventos de burbujeo, que es una historia diferente - Nota: el burbujeo no está restringido a eventos relacionados con JavaScript o DOM, por ejemplo ).

Usar eventos personalizados con tus propios objetos es muy normal. Como Evan Yu mencionó , hay bibliotecas para esto. Aquí hay una pareja:

He usado js-signals y me gusta bastante. Nunca he usado Wolfy87/EventEmitter , pero tiene un buen aspecto.

Su ejemplo puede parecerse al siguiente si utilizó js-signals

jsFiddle

var iSubmit = { finished: new signals.Signal(), test: function test(memo) { this.finished.dispatch(memo || {}); } }; iSubmit.finished.add(function(data) { console.log(''finished:'', data); }); iSubmit.test(''this is the finished data''); // alternatively iSubmit.finished.dispatch(''this is dispatched directly from the signal'');


Si desea escuchar un objeto javascript, tiene tres formas:

Sobre el patrón sup / pub:

Necesitas publicar eventos.

Acerca de las implementaciones nativas:

  • Object get/set operators son suficientes para escuchar agregar, eliminar, cambiar, obtener eventos. Los operadores tienen buen support . Problemas solo en IE8-. Pero si quiere usar get / set en IE8, use Object.defineProperty pero en objetos DOM o use Object.fineProperty sham .
  • Object.prototype.watch tiene el buen polyfill ES5.
  • Proxy API necesita compatibilidad con ES Harmony.

Object.observe example

var o = {}; Object.observe(o, function (changes) { changes.forEach(function (change) { // change.object contains changed object version console.log(''property:'', change.name, ''type:'', change.type); }); }); o.x = 1 // property: x type: add o.x = 2 // property: x type: update delete o.x // property: x type: delete


Si no necesita funciones de eventos verdaderos (como el burbujeo, detener la propagación), puede implementar sus propios eventos. addEventListener es solo una API del DOM, por lo que realmente no la necesita para sus propios objetos fuera del DOM. Si desea crear un patrón recortado alrededor de un objeto, esta es una buena forma de hacerlo que no requiere ninguna API de navegador adicional y debe ser compatible con versiones anteriores.

Supongamos que tiene un objeto en el que desea desencadenar varios eventos cuando se llama al método de envío:

var OurDispatcher, dispatcher; OurDispatcher = (function() { function OurDispatcher() { this.dispatchHandlers = []; } OurDispatcher.prototype.on = function(eventName, handler) { switch (eventName) { case "dispatch": return this.dispatchHandlers.push(handler); case "somethingElse": return alert(''write something for this event :)''); } }; OurDispatcher.prototype.dispatch = function() { var handler, i, len, ref; ref = this.dispatchHandlers; for (i = 0, len = ref.length; i < len; i++) { handler = ref[i]; setTimeout(handler, 0); } }; return OurDispatcher; })(); dispatcher = new OurDispatcher(); dispatcher.on("dispatch", function() { return document.body.innerHTML += "DISPATCHED</br>"; }); dispatcher.on("dispatch", function() { return document.body.innerHTML += "DISPATCHED AGAIN</br>"; }); dispatcher.dispatch();

Realmente no tiene que ser más complicado que eso, en su mayor parte. De esta manera, tendrá un control decente sobre sus eventos y no tendrá que preocuparse por la compatibilidad con versiones anteriores o las bibliotecas externas, ya que todo es ampliamente compatible. Técnicamente, incluso podría hacerlo sin setTimeout y manejar sus devoluciones de llamadas sin ninguna API. Cualquier otra cosa como stopPropagation () tendría que ser manejada por ti mismo.

https://jsfiddle.net/ozsywxer/

Hay, por supuesto, polyfills para CustomEvent, pero a menos que necesite características avanzadas de eventos, prefiero envolver mi propio sistema de eventos en una "clase" y extender otras clases / funciones con él.

Aquí está la versión de CoffeeScript, que es de lo que se deriva el JavaScript: https://jsfiddle.net/vmkkbbxq/1/

^^ Un poco más fácil de entender.


Si se encuentra en un entorno Node.js, puede usar la clase EventEmitter de Node :

CustomObject.js

const EventEmitter = require(''events''); class CustomObject extends EventEmitter { constructor() { super(); } doSomething() { const event = {message: ''Hello World!''}; this.emit(''myEventName'', event); } } module.exports = CustomObject;

Uso:

const CustomObject = require(''./CustomObject''); // 1. Create a new instance const myObject = new CustomObject(); // 2. Subscribe to events with ID "myEventName" myObject.on(''myEventName'', function(event) { console.log(''Received event'', event); }); // 3. Trigger the event emitter myObject.doSomething();

Si desea usar EventEmitter de Node fuera de un entorno Node.js, puede usar el webpack (preferiblemente v2.2 o posterior) para obtener un paquete de su CustomClass junto con un eventfile Polyfill (construido por webpack).

Así es como funciona (suponiendo que haya instalado el paquete web globalmente usando npm install -g webpack ):

  1. Ejecutar el webpack CustomObject.js bundle.js --output-library=CustomObject
  2. Incluya bundle.js en su página HTML (expondrá window.CustomObject )
  3. ¡No hay paso tres!

index.html

<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Title</title> <script src="bundle.js"></script> </head> <body> <script> // 1. Create a new instance const myObject = new window.CustomObject(); // 2. Subscribe to events with ID "myEventName" myObject.on(''myEventName'', function(event) { console.log(''Received event'', event); }); // 3. Trigger the event emitter myObject.doSomething(); </script> </body> </html>


Solo especulación; No lo he probado yo mismo. Pero puedes crear un elemento ficticio y disparar / escuchar eventos en el elemento ficticio. Además, prefiero ir sin bibliotecas.

function myObject(){ //create "dummy" element var dummy = document.createElement(''dummy''); //method for listening for events this.on = function(event, func){dummy.addEventListener(event, func);}; //you need a way to fire events this.fireEvent = function(event, obj){ dummy.dispatchEvent(new CustomEvent(event, {detail: obj})); } } //now you can use the methods in the object constructor var obj = new myObject(); obj.on("custom", function(e){console.log(e.detail.result)}); obj.fireEvent("custom", {result: "hello world!!!"});


Uso: jsfiddle

Este es un enfoque ingenuo pero podría funcionar para algunas aplicaciones:

CustomEventTarget.prototype = { ''constructor'': CustomEventTarget, on: function( ev, el ) { this.eventTarget.addEventListener( ev, el ) }, off: function( ev, el ) { this.eventTarget.removeEventListener( ev, el ) }, emit: function( ev ) { this.eventTarget.dispatchEvent( ev ) } } function CustomEventTarget() { this.eventTarget = new EventTarget }


addEventListener está destinado a DOM Elementos que implementa ciertas interfaces relacionadas con eventos. Si desea un sistema de eventos en objetos de JavaScript puros, está buscando un sistema de eventos personalizado. Un ejemplo sería Backbone.Events en Backbone.js. La idea básica es usar un objeto como un hash para realizar un seguimiento de las devoluciones de llamada registradas.

Personalmente uso esto: https://github.com/component/emitter

Es una solución bastante simple y elegante, con nombres de métodos pequeños y dulces como on() , off() y emit() . puede crear nuevas instancias con el new Emitter() o usar Emitter(obj) para mezclar capacidades de eventos en objetos existentes. Tenga en cuenta que esta biblioteca está escrita para su uso con un sistema de módulos CommonJS, pero puede usarla en cualquier otro lugar eliminando module.exports = ... line.