Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private non-static variables in polymer?

How is it possible to have private non-static variables in polymer?

In:

<polymer-element name="component-one">
   <script>

       Polymer('component-one', {
       internalState = 1,    
       ready() {
               this.anotherInternalState = 1;
           }
           /* more variables and functions */
      });

   </script>

</polymer-element>

both internalState and anotherInernalState are exposed to outside (e.g. accessible through something like:

document.querySelector('component-one').internalState

(Which might be undesirable when changing internalState from outside makes the component unstable.)

where as in:

<polymer-element name="component-two">
   <script>

    (function() { 

       var internalState = 1;


       Polymer('component-two', {
          /* some variables and functions */
      });
    })();

   </script>

</polymer-element>

internalState is hidden from outside but it is static and shared across all the instances of the component.

Is there a way to have a private non-static variable inside polymer object?

like image 356
sepans Avatar asked Jun 27 '14 21:06

sepans


2 Answers

This is more of a pure JavaScript question than a Polymer question. As of ES5 there are no 'private instance members' in JavaScript, although ES6 brings some new tools.

My suggestion is to use the old convention of prepending private instance variables with underscore (_internalState).

Otherwise, you have to get tricky with maps and closures.

like image 88
Scott Miles Avatar answered Nov 16 '22 14:11

Scott Miles


You'd have to maintain a private static context for each instance of your element. There are some hints in the doc as to how to do that. First off I'd start with keeping track of live instances:

var instances = [];
Polymer('foo-bar', {
    // ...
    attached: function() {
        instances.push(this);
    },
    detached: function(){
        instances = instances.filter(function(instance){
            return instance !== this;
        }.bind(this));
    },
    // ...
});

Then you could add a private method to get access to your instance private context:

var instances = [], contexts = [];
Polymer(/* ... */);
function getPrivateContext(instance){
    return contexts[instances.indexOf(instance)];
}

And wire it up all together more elegantly:

var instances = [];
Polymer('foo-bar', {
    // ...
    attached: function() {
        instances.push({
            element: this,
            context: {}
        );
    },
    detached: function(){
        instances = instances.filter(function(instance){
            return instance.element !== this;
        }.bind(this));
    },
    // ...
    whatever: function(){
        var privateThis = private(this);
    }
});
function private(element){
    return instances.filter(function(instance){
        return instance.element === element;
    })[0].context;
}

Haven't tested it but it should work.

like image 31
Renaud Avatar answered Nov 16 '22 14:11

Renaud