mercredi 22 juillet 2015

Private prototype methods that can share scope and access the instance

I'm looking for a pattern that both allows me to create a private scope that my function prototype has access to and I need to be able to access the instance from within that scope.

For example, this is how I am currently achieving "private methods" (disregard what the code actually does, just look at the structure.)

function InfoPreview() {
   this.element = document.createElement('div');
}

//Private Methods
InfoPreview.prototype.__newLine = function () {
  this.element.appendChild(createElement({tagName:'br'}));
}; 

InfoPreview.prototype.__padLeft = function(level) {
  var padding = createElement({tagName: 'span'});
  this.element.appendChild(padding);
  $(padding).width(level * 10);
};

InfoPreview.prototype.__print = function(string) {
  var span = createElement({ tagName: 'span', textContent: string });
  this.element.appendChild(span);
  this.element.style["margin-right"]='10px';
};

InfoPreview.prototype.__puts = function(string) {
  this.__print(string);
  this.__newLine();
};

//Public Methods
InfoPreview.prototype.update = function(info) {
  $(this.element).empty();
  for (var record in info) {
    this.__puts(record);
  }
};   

Notice that I am not creating private methods at all, just utilizing a naming convention. Additionally notice that I have no way to cache chain-lookups, such as this.element.

I would like to create a private scope by utilizing a revealing module pattern, like this:

InfoPreview.prototype = (function() {
  var self = this, //<- `this` is actually the global object now.
      el = self.element;

  var newLine = function () {
    el.appendChild(createElement({tagName:'br'}));
  }; 

  var padLeft = function(level) {
    var padding = createElement({tagName: 'span'});
    el.appendChild(padding);
    $(padding).width(level * 10);
  };

  var print = function(string) {
    var span = createElement({ tagName: 'span', textContent: string });
    el.appendChild(span);
    el.style["margin-right"]='10px';
  };

  var puts = function(string) {
    print(string);
    newLine();
  };

  var update = function(info) {
    $(el).empty();
    for (var record in info) {
      puts(record);
    }
  };

  return {
    update: update
  }; 
})();

The above approach doesn't work however, because the value of this within the IIFE is the global object, not the instance. I need a way to access the instance.

Aucun commentaire:

Enregistrer un commentaire