2013-09-28 286 views
5

Tôi đã cố tạo một danh sách đơn giản với tiện ích phụ thêm làm thành phần Emberjs.Trạng thái được chia sẻ trong thành phần Ember

Sau đây là đoạn code tôi sử dụng:

HTML:

<!DOCTYPE html> 
<html> 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0/handlebars.js"></script> 
<script src="http://cdnjs.cloudflare.com/ajax/libs/ember.js/1.0.0/ember.min.js"></script> 
<meta charset=utf-8 /> 
<title>Ember Component example</title> 
</head> 
<body> 

    <script type="text/x-handlebars" id="components/appendable-list"> 
    <h2> An appendable list </h2> 
    <ul> 
     {{#each item in myList}} 
     <li> {{item}} </li> 
     {{/each}} 
    </ul> 
    {{input type="text" value=newItem}} 
    <button {{action 'append'}}> Append Item </button> 
    </script> 

    <script type="text/x-handlebars"> 
    {{appendable-list}} 
    {{appendable-list}} 
    </script> 

</body> 
</html> 

Javascript:

App = Ember.Application.create(); 

App.AppendableListComponent = Ember.Component.extend({ 
    theList: Ember.ArrayProxy.create({ content: [] }), 
    actions: { 
     appendItem: function(){ 
      var newItem = this.get('newItem'); 
      this.get('theList').pushObject(newItem); 
     } 
    } 
}); 

Trong trường hợp đó, danh sách được chia sẻ giữa hai trường hợp (có nghĩa là, gắn thêm vào một phụ lục trong phần khác)

Đây là JsBin để kiểm tra: http://jsbin.com/arACoqa/7/edit?html,js,output

Nếu tôi làm như sau, nó hoạt động:

window.App = Ember.Application.create(); 

App.AppendableListComponent = Ember.Component.extend({ 
    didInsertElement: function(){ 
    this.set('myList', Ember.ArrayProxy.create({content: []})); 
    }, 
    actions: { 
    append: function(){ 
     var newItem = this.get('newItem'); 
     this.get('myList').pushObject(newItem); 
    } 
    } 
}); 

Đây là JsBin: http://jsbin.com/arACoqa/8/edit?html,js,output

Tôi đang làm gì sai? Cảm ơn trước!

Trả lời

7

Sau khi bạn khai báo các thành phần, mỗi khi bạn sử dụng nó trong mẫu của bạn một trường hợp mới sẽ là được tạo ra và quan trọng nhất là móc init cũng sẽ được gọi mỗi khi một cá thể mới được khởi tạo, do đó cách an toàn nhất để có các mảng myList khác nhau là sử dụng móc init thành phần, để khởi tạo mảng, vì vậy, hãy thử như sau:

App.AppendableListComponent = Ember.Component.extend({ 
    myList: null, 
    init: function(){ 
    this._super(); 
    this.set('myList', Ember.ArrayProxy.create({content: []})); 
    }, 
    actions: { 
    append: function(){ 
     var newItem = this.get('newItem'); 
     this.get('myList').pushObject(newItem); 
    } 
    } 
}); 

Cũng quan trọng là gọi this._super(); bên trong init và mọi thứ sẽ hoạt động như mong đợi.

Xem tại đây để làm việc demo.

Hy vọng điều đó sẽ hữu ích.

+0

Tuyệt vời! Tôi nghĩ cách của bạn sạch hơn rất nhiều. Cảm ơn bạn! – tcbpg

+1

Rất tiếc! Tôi có thể thề tôi đã làm. Hy vọng nó đã được sửa. – tcbpg

3

Khi bạn sử dụng extend(hash) bất kỳ giá trị nào có trong giá trị băm, sẽ được sao chép vào bất kỳ phiên bản được tạo nào. Và bởi vì mảng là một đối tượng, bạn tham khảo sẽ giống nhau trên các đối tượng được tạo:

App.MyObject = Ember.Object.extend({ text: [] }); 

obj1 = App.MyObject.create(); 
obj2 = App.MyObject.create(); 

obj1.get('text') === obj2.get('text') // true 

obj1.get('text').pushObject('lorem'); 
obj1.get('text'); // ["lorem"] 

obj2.get('text').pushObject('ipsum'); 
obj2.get('text'); // ["lorem", "ipsum"] 

Các didInsertElement được gọi là cho mỗi điểm mới được tạo ra, và xem từng là một trường hợp khác nhau. Vì vậy, với thực hiện của bạn, bạn sẽ luôn luôn có một trường hợp Ember.ArrayProxy mới cho mỗi view, sau đó không một quốc gia chia sẻ tồn tại:

didInsertElement: function() { 
    // each call for this method have a diferent instance 
    this.set('myList', Ember.ArrayProxy.create({content: []})); 
} 
+0

Ồ, tôi hiểu, cảm ơn bạn đã giải thích! – tcbpg