2014-06-27 29 views
11

如何在聚合物中存在私有的非靜態變量?聚合物中的私有非靜態變量?

在:

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

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

    </script> 

</polymer-element> 

internalState和anotherInernalState都暴露於外部(例如,通過類似訪問:

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

(從外部改變internalState時,這可能是不希望使組件不穩定。 )

其中:

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

    (function() { 

     var internalState = 1; 


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

    </script> 

</polymer-element> 

internalState從外部隱藏,但它是靜態的並在組件的所有實例之間共享。

有沒有辦法在聚合物對象內部有一個私有的非靜態變量?

回答

4

這是一個比Polymer問題更純粹的JavaScript問題。從ES5開始,JavaScript中沒有'私有實例成員',儘管ES6帶來了一些新的工具。

我的建議是使用前綴私有實例變量和下劃線的舊慣例(_internalState)。

否則,你必須對地圖和閉包變得棘手。

+0

感謝Scott,我只是看着FB React,看到React有一個屬於該組件的狀態屬性。是不是有用到足以加入聚合物的東西? (對我的愚見來說,它是:) – sepans

+1

鏈接:http://facebook.github.io/react/docs/tutorial.html#reactive-state – sepans

+0

希望這個功能是建議在0.8和1.0 API – andrsnn

-1

下面是我採取的方法:

<script type="text/javascript">   
    (function() { 
     var privateStatic = Math.random(); 

     function ContactCard(component) { 
      var mouseoverTimer; 
      var privateInstance = Math.random(); 

      component.addEventListener('mouseenter', function() { 
       mouseoverTimer = setTimeout(function() { 
        alert(privateStatic); 
        alert(privateInstance); 
       }, 250); 
      }); 

      component.addEventListener('mouseleave', function() { 
       clearTimeout(mouseoverTimer); 
      }); 

      return { 

      }; 
     }; 

     Polymer({ 
      ready: function() { 
       new ContactCard(this); 
      } 
     }); 
    })(); 
</script> 

我沒有表現出來的例子,但你仍然可以使用的影子根通過ID訪問元素的component.$.someElementId方式。

另外:我覺得這種編程風格可以讓你將組件從Polymer進一步分離出來,如果你遇到這種情況的話。實際上,你可以使用component.shadowRoot.getElementById('someElementId')component.shadowRoot.querySelector('#someElementId')以及其他戰術,如果你選擇,他們會在其他瀏覽器,除了鉻

-1

只需推動價值分配中的原型功能之一,像(包括IE9及以上):

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

     (function() { 

      var internalState; 

      Polymer('component-two', { 

       ready: function() { 
        internalState = 1; // Replace static value with something instance specific 
       } 
      }); 
     })(); 

    </script> 
</polymer-element> 
+0

忘記了,wasn'沒想到! – nikvm

+0

但是如何聲明一個私有靜態數組?然後,在其中一個原型函數中將值推送到該數組並保存索引,如'this.index = internalState.push(someValue) - 1;'並使用'internalState [this.index]'訪問它。這隻會暴露''元素之外的索引。另外一個''元素仍然可以訪問另一個實例的「internalState」。 – nikvm

0

在ES6,你有符號,你用符號可以做

<polymer-element name="my-element"> 
    <script type="text/javascript">   
     (function() { 
      // visible to all my-element instances 
      var privateKey = Symbol('Symbol description'); 

      Polymer({ 
       ready: function() { 
        // initialize object containing private properties 
        this[privateKey] = {}; // only you can touch this 

        // only those with access to 'privateKey' can can access 
        // your new ContactCard 
        this[privateKey].contactCard = new ContactCard(this); 
       }, 
       // public method 
       publicMethod: function() { 

        // accessing private data 
        doSomethingWith(this[privateKey].contactCard); 
       } 
      };); 
     })(); 
    </script> 
</polymer-element> 

。這應該阻止您的元素的用戶訪問您選擇的某些數據。由於所有實例都可以查看密鑰,所以數據對於元素的所有實例都是可見的。更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

1

您必須爲元素的每個實例維護一個私有靜態上下文。文檔中有some hints關於如何做到這一點。

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

然後,你可以添加一個私有方法來獲得您的實例私有上下文的訪問:

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

,並將其連接起來一起更首先,我想要與跟蹤現場情況的開始優雅地:

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; 
} 

沒有測試它,但它應該工作。