how to implement observer pattern in javascript?

前端 未结 9 1550
执笔经年
执笔经年 2021-01-30 07:29

Hi I\'m tyring to implement observer pattern in JavaScript:

My index.js:

$(document).ready(function () {
  var ironMan = new Movie();
           


        
相关标签:
9条回答
  • 2021-01-30 08:25

    Here's an implementation of the Observer pattern in JavaScript that provides an API very similar to Backbone Models. This implementation avoids use of "this" and "new", as suggested by 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;
            });
          }
        }
      };
    }
    

    Here's some example code that uses 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"
    
    0 讨论(0)
  • 2021-01-30 08:25

    The observer pattern is all about updating an object and having those updates automatically send out an event that gives info about what was updated.

    For example:

    function ObserverList(){
      this.observerList = []
      this.listeners = []
    }
    
    ObserverList.prototype.add = function( obj ){
      this.observerList.push(obj)
      this.listeners.forEach(function(callback){
        callback({type:'add', obj:obj})
      })
    }
    
    ObserverList.prototype.onChange = function(callback){
      this.listeners.push(callback)
    }
    

    Here's a module of the observer pattern in javascript, you can take a look at the source code fore more info: https://github.com/Tixit/observe

    0 讨论(0)
  • 2021-01-30 08:28

    This is old, but I wanted to provide an answer to the original question, "how to implement the observer pattern given the existing code".

    The Observer pattern can be simplified as a communication design where the target (the thing being observed) has a pointer to the observer(s) and assumes a public API for an observer. For example, the target assumes that an observer has a method called update or that an observer is a Function. It's how a target notifies observers of changes, by actually calling a method on the observer object (or Function if the observer is a function).

    Any time a property is mutated or changed, the target must update all observers that have registered to be notified.

    Here, I'm assuming that you want to know how to implement a Key-Value Observer. In which case, the code will have to iterate over its observer list and call each observers update method (or just execute the observer in the case where it's a Function) when a property is changed.

    var observers = null;
    
    function Movie() {
     observers = new ObserverList();
    }
    
    Movie.prototype.changed = function(key, old, value){
      // Assumption here is that observers can observe individual properties.
      if(!this.observers[key]) return
      
      this.observers[key].forEach( o => {
        // Assumption is that observers have an update method. This is the only
        // thing the target knows about an observer.
          o.update(key, old, value, this)
      })
    
    }
    
    // Now every setter on the target has to notify the observers by calling `changed`
    Movie.prototype.setTitle = function (newTitle) {
      var old = this.title;
      this.title = newTitle;
      this.changed("title", old, this.title, this)
    }

    you'd have to add that changed method and then update all the setter methods to call changed as per above.

    I also noticed that there's nowhere in the original code that observes the movie. You'll need to add code that actually observes it, something that implements update, given my example above.

    I'm unsure what the intent is for play and stop.

    0 讨论(0)
提交回复
热议问题