2013-09-28 3 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 было бы использовать компонентный крючок для инициализации массива, поэтому попробуйте следующее:

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

Также важно это позвонить this._super(); внутри init и все будет работать так, как ожидалось.

См. Здесь для работы 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

Смежные вопросы