Saltar al contenido

¿Cómo implementar el patrón de observador en javascript?

Necesitamos tu ayuda para extender nuestras reseñas acerca de las ciencias de la computación.

Solución:

JavaScript es evento conducido: Eso significa que es consciente del tiempo y espera que las cosas cambien con el tiempo. El patrón Observer original se creó para lenguajes como C++ que no son conscientes del tiempo. Puede aprovechar las fortalezas de JavaScript usando un bucle de juego para comprobar los cambios de estado.

Crea dos elementos DOM, una entrada y una salida.


Configurar un requestAnimationFrame bucle y empezar a observar.

//Get a reference to the input and output
var input = document.querySelector("input");
var output = document.querySelector("#output");

//Set up a requestAnimationFrame loop
function update () 
  requestAnimationFrame(update);

  //Change the output to match the input
  output.innerHTML = input.value;

update(); 

Esto es lo que hacen los motores de juegos modo inmediato representación. También es lo que hace el marco React para verificar los cambios de estado en el DOM.

(Si lo necesita, aquí hay una solicitud simpleAnimationPolyfill)

//Polyfill for requestAnimationFrame
window.requestAnimationFrame = (function())();

En JavaScript, no tiene sentido implementar un patrón de observador puro como en Java, porque JavaScript tiene esta pequeña cosa llamada programación funcional. Así que solo use algo como http://api.jquery.com/category/callbacks-object/ en lugar de su ObserverList.

Si aún desea usar su objeto, todo depende de lo que desee pasar a ObserverList.Add. Si es algún objeto, entonces necesitas escribir

for( i = 0; i < observers.Count; i++)  
  observers[i].Notify("some data"); 

Si es una función entonces necesitas escribir

for( i = 0; i < observers.Count; i++)  
  observers[i]("Some data"); 

También puede usar Function.apply() o Function.call() para suministrar this a tu funcion

Aquí hay una implementación del patrón Observer en JavaScript que proporciona una API muy similar a Backbone Models. Esta implementación evita el uso de "esto" y "nuevo", como sugiere Douglas Crockford.

// The constructor function.
function Model()

  // An object containing callback functions.
  //  * Keys are property names
  //  * Values are arrays of callback functions
  var callbacks = ,

      // An object containing property values.
      //  * Keys are property names
      //  * Values are values set on the model
      values = ;

  // Return the public Model API,
  // using the revealing module pattern.
  return 

    // Gets a value from the model.
    get: function(key)
      return values[key];
    ,

    // Sets a value on the model and
    // invokes callbacks added for the property,
    // passing the new value into the callback.
    set: function(key, value)
      values[key] = value;
      if(callbacks[key])
        callbacks[key].forEach(function (callback) 
          callback(value);
        );
      
    ,

    // Adds a callback that will listen for changes
    // to the specified property.
    on: function(key, callbackToAdd)
      if(!callbacks[key])
        callbacks[key] = [];
      
      callbacks[key].push(callbackToAdd);
    ,

    // Removes a callback that listening for changes
    // to the specified property.
    off: function(key, callbackToRemove)
      if(callbacks[key])
        callbacks[key] = callbacks[key].filter(function (callback) 
          return callback !== callbackToRemove;
        );
      
    
  ;

Aquí hay un código de ejemplo que usa Model:

// Create a new model.
var model = Model();

// Create callbacks for X and Y properties.
function listenX(x)
  // The new value is passed to the callback.
  console.log('x changed to ' + x);


function listenY(y)
  // The new value can be extracted from the model.
  console.log('y changed to ' + model.get('y'));


// Add callbacks as observers to the model.
model.on('x', listenX);
model.on('y', listenY);

// Set values of X and Y.
model.set('x', 30); // prints "x changed to 30"
model.set('y', 40); // prints "y changed to 40"

// Remove one listener.
model.off('x', listenX);
model.set('x', 360); // prints nothing
model.set('y', 50); // prints "y changed to 40"

Puedes confirmar nuestro estudio mostrando un comentario o dejando una puntuación te damos la bienvenida.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *