2013-09-28 75 views
5

我試圖用附加部件構建一個簡單列表作爲Emberjs組件。Ember組件中的共享狀態

以下是我使用的代碼:

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

在這種情況下,在列表中的兩個實例之間共享(即,附加在一個附加在另一個)

這裏是JsBin檢查出來:http://jsbin.com/arACoqa/7/edit?html,js,output

如果我這樣做,它的工作原理:

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

這裏是JsBin:http://jsbin.com/arACoqa/8/edit?html,js,output

我在做什麼錯?提前致謝!

回答

7

後聲明的組件,每次使用它在你的模板的新實例將時間創建,最重要的是,每當新實例被實例化時,也會調用init掛鉤,因此具有不同myList數組的最安全的方法是使用組件init掛鉤來初始化數組,因此請嘗試以下操作:

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

同樣重要在init內部撥打this._super();,一切按預期工作。

看到這裏工作demo

希望它有幫助。

+0

太棒了!我認爲你的方式更清潔。謝謝! – tcbpg

+1

糟糕!我可以發誓我做到了。希望它是固定的。 – tcbpg

3

當您使用extend(hash)散列中存在的任何值將被複制到任何創建的實例。而且由於數組是一個對象,你的引用將橫跨創建的對象相同:

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

didInsertElement被稱爲爲每個新創建的視圖,每個視圖是一個diferent實例。因此,與您的實現,你總是會有一個新的Ember.ArrayProxy實例爲每個視圖,然後沒有共享的狀態存在:

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

哦,我明白了,謝謝你的解釋! – tcbpg