2014-06-27 18 views
11

Làm thế nào để có thể có biến không riêng tư trong polymer?Biến phi tĩnh riêng trong polymer?

Trong:

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

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

    </script> 

</polymer-element> 

cả internalState và anotherInernalState được tiếp xúc với bên ngoài (ví dụ như truy cập thông qua một cái gì đó như:

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

(Trong đó có thể không mong muốn khi thay đổi internalState từ bên ngoài làm cho các thành phần không ổn định.)

nơi ở:

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

    (function() { 

     var internalState = 1; 


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

    </script> 

</polymer-element> 

internalState được ẩn từ bên ngoài nhưng nó tĩnh và được chia sẻ trên tất cả các phiên bản của thành phần.

Có cách nào để có biến không phải riêng tư bên trong đối tượng polymer không?

Trả lời

4

Đây là câu hỏi JavaScript thuần túy hơn câu hỏi về Polymer. Vì ES5 không có 'thành viên cá thể riêng' trong JavaScript, mặc dù ES6 mang lại một số công cụ mới.

Đề xuất của tôi là sử dụng quy ước cũ về các biến cá thể riêng tư trước có dấu gạch dưới (_internalState).

Nếu không, bạn phải khéo léo với bản đồ và đóng cửa.

+0

Cảm ơn Scott, tôi vừa xem xét FB React và thấy rằng React có thuộc tính trạng thái riêng tư đối với thành phần. Chẳng phải cái gì cũng đủ hữu ích để được thêm vào Polymer sao? (theo ý kiến ​​khiêm nhường của tôi là :) – sepans

+1

liên kết: http://facebook.github.io/react/docs/tutorial.html#reactive-state – sepans

+0

Hy vọng tính năng này được đề xuất trong 0.8 và 1.0 API – andrsnn

-1

Dưới đây là cách tiếp cận tôi đã thực hiện:

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

Tôi không hiển thị nó trong ví dụ này, nhưng bạn vẫn có thể sử dụng cách tiếp cận component.$.someElementId yếu tố bởi id trong thư mục gốc bóng.

Ngoài ra: Tôi cảm thấy kiểu lập trình này cho phép bạn tách rời các thành phần của mình xa hơn một chút so với Polymer nếu bạn thích điều đó. Bạn thực sự có thể sử dụng component.shadowRoot.getElementById('someElementId')component.shadowRoot.querySelector('#someElementId') cũng như các chiến thuật khác nếu bạn chọn và chúng sẽ hoạt động trong các trình duyệt khác ngoài Chrome (bao gồm IE9 trở lên).

-1

Chỉ cần chuyển nhượng giá trị trong một trong các chức năng mẫu, như:

<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

Quên điều đó, wasn ' t suy nghĩ! – nikvm

+0

Nhưng làm thế nào về tuyên bố một mảng tĩnh tư nhân? Sau đó, trong một trong các hàm nguyên mẫu đẩy một giá trị vào mảng đó và lưu chỉ mục như 'this.index = internalState.push (someValue) - 1;' và truy cập nó bằng 'internalState [this.index]'. Điều này sẽ chỉ phơi bày chỉ mục bên ngoài các phần tử ''. Ngoài ra một phần tử '' sẽ vẫn có thể truy cập vào "internalState" của một cá thể khác. – nikvm

0

Trong ES6, nơi bạn có biểu tượng, bạn có thể làm

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

sử dụng biểu tượng. Điều này sẽ ngăn người dùng yếu tố của bạn truy cập vào dữ liệu nhất định mà bạn chọn. Vì tất cả các trường hợp có thể xem khóa, dữ liệu vẫn hiển thị cho tất cả các phiên bản của phần tử của bạn. Thông tin thêm: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

1

Bạn sẽ phải duy trì ngữ cảnh tĩnh riêng cho từng phiên bản của phần tử của bạn. Có some hints trong tài liệu về cách thực hiện điều đó.Trước hết tôi muốn bắt đầu với việc theo dõi các trường hợp trực tiếp:

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

Sau đó, bạn có thể thêm một phương pháp riêng để có được quyền truy cập vào ngữ cảnh của bạn Ví dụ tin:

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

Và dây nó lên tất cả cùng nhau hơn thanh lịch:

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

Chưa thử nghiệm nhưng nó sẽ hoạt động.