Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private and public variables to a backbone view

In a backbone view where would you put your private variables and your public.

Right now I have something like this:

myView = Backbone.View.extend({

  initialize: function(options){
    this.myPublic = "I'm public";
  }

});

I tried adding a var myPrivate before the initialize method but it threw an error. Where would private variables that are only used within the view go?

like image 641
Chapsterj Avatar asked Sep 27 '11 21:09

Chapsterj


3 Answers

I suggest you use the initialize method as a closure around all other methods. I think this will give you behaviour more consistent with what we get in classical inheritance languages like C++ and Java:


myView = Backbone.View.extend({

  initialize: function(options){
    var myPrivate = "I'm private";

    this.myPublic = "I'm public";

    this.getPrivate = function () {
      return myPrivate;
    };

    this.setPrivate = function (value) {
        if (typeof(value) === 'string') {
            myPrivate = value;
            return true;
        } else {
            return false;
        }
    };
  }
});
like image 145
Near Privman Avatar answered Nov 13 '22 09:11

Near Privman


Wrap it all up in a self-invoking anonymous function:

(function() {
    var myPrivate = 1;

    myView = Backbone.View.extend({  
        initialize: function(options){  
            this.myPublic = "I'm public";
            myPrivate++;
        },
        render: function() {
            alert(myPrivate);
        }
    });

})();

Edit: As pointed out in kaustubh's comment below, the above example creates a private variable that is shared among the instances. You could create a sort of protected variable, that is, an instance level variable that could be read by other instances of the View. Give each instance a unique public id and store instance variables in a "private static" variable. Then access the variables by instance id:

(function() {
    var data = [];

    myView = Backbone.View.extend({  
        initialize: function(options){  
            this.myPublic = "I'm public";
            this.Id = data.length;
            data.push({});
            data[this.Id].myProtected = "abc";
        },
        render: function() {
            alert(data[this.Id].myProtected)
        }
    });
})();

Or, you can do it without using a public id, but it becomes a bit more convoluted:

(function() {
    var data = (function () {
        var dataValues = [];
        return function (instance) {
            for (var i = 0; i < dataValues.length; i++) {
                if (dataValues[i].instance === instance) {
                    return dataValues[i].data;
                }
            }
            var dataObject = { instance: instance, data: {} };
            dataValues.push(dataObject);
            return dataObject.data;
        };
    })();

    myView = Backbone.View.extend({
        initialize: function(options){  
            this.myPublic = "I'm public";
            data(this).myProtected = "abc";
        },
        render: function() {
            alert(data(this).myProtected)
        }
    });
})();

I'm struggling to come up with a way of storing truly private variables. I'll post back if inspiration strikes.

like image 45
gilly3 Avatar answered Nov 13 '22 08:11

gilly3


Instead of inserting the object directly into the extend function, how about creating a closure and from that closure return an object to the extend function?

var myView = Backbone.View.extend(function () {

  var _myPrivateOne = 0;

  function _myPrivateStrangeSquareFunction(a) {
    return a * a + 1;
  }

  return {
    initialize: function (options) {
      _myPrivateOne = options.privateOne;
      this.myPublicOne = options.publicOne;
    },
    setPrivateOne: function (value) {
      _myPrivateOne = value;
      return _myPrivateOne;
    },
    getPrivateOne: function () {
      return _myPrivateOne;
    },
    getPrivateOneStrangelySquared: function () {
      return _myPrivateStrangeSquareFunction(_myPrivateOne);
    }
  };

} ());

I haven't tried this, because I have no Backbone install available right now.

like image 1
jgroenen Avatar answered Nov 13 '22 09:11

jgroenen