2016-09-01 2 views
0

Каждый раз, когда я звоню Ext.create(), новая кнопка подталкивается к форме. Но counter все еще оставляют == 1Почему свойства объектов ExtJS ведут себя как статические?

Если удалить items: [] и раскомментируйте Ext.apply(/*...*/) все работает правильно.

Почему недвижимость items ведет себя как статическая?

Ext.application({ 
    name : 'Fiddle', 

    launch : function() { 
     Ext.define('TestForm', { 
      extend: 'Ext.form.Panel', 
      title: 'TestForm', 
      margin: 40, 
      items: [], // remove it 
      counter: 100, 
      initComponent: function() { 
       this.counter++; 
       /*Ext.applyIf(this, { 
        items: [] 
       });*/ 
       this.items.push({ xtype: 'button', text: 'test'+this.counter}) 
       this.callParent(arguments); 
      }, 
      renderTo: Ext.getBody() 
     }) 

     Ext.create('TestForm'); 
     Ext.create('TestForm'); 
     Ext.create('TestForm'); 
    } 
}); 

ответ

0

Когда компонент получен из прототипа, все элементы передаются - некоторые по ссылке, некоторые по значению, в зависимости от типа.

  • Счетчик - это int, который передается по значению.
  • Элементы представляют собой массив, который передается по ссылке.

Так что, если вы определяете items массив на прототипе, все экземпляры указывают на то же items массив.

Поскольку вы добавляете конфигурацию кнопки в этот массив (на котором есть две ссылки, одна из прототипа и одна из экземпляра), каждый раз, когда вы создаете новый экземпляр, в этот массив добавляется новая кнопка, сохраняя старые.

Впоследствии, в callParent, ExtJS выполняет итерацию над свойством items (затем массив) и создает MixedCollection компонентов из содержимого массива. Затем mixedCollection сохраняется в свойстве items. Во время этого эта ссылка ломается - вот почему первый экземпляр не получает вторую кнопку в своих элементах.

Чтобы убедиться, что вы не сталкиваетесь с этими проблемами, существует одна возможность: Никогда не определяйте типы сквозной ссылки как элементы прототипа.

Что бы я сделал:

Ext.define('TestForm', { 
     extend: 'Ext.form.Panel', 
     title: 'TestForm', 
     margin: 40, 
     counter: 100, 
     initComponent: function() { 
      this.counter++; 
      Ext.apply(this, { 
       items: [{ xtype: 'button', text: 'test'+this.counter}] 
      }); 
      this.callParent(arguments); 
     }, 
     renderTo: Ext.getBody() 
    }) 

или

Ext.define('TestForm', { 
     extend: 'Ext.form.Panel', 
     title: 'TestForm', 
     margin: 40, 
     counter: 100, 
     initComponent: function() { 
      this.counter++; 
      this.callParent(arguments); 
      this.add({xtype: 'button', text: 'test'+this.counter}); 
     }, 
     renderTo: Ext.getBody() 
    }) 

Первый добавляет определение пунктов в каждом конкретном случае, прежде чем он конкретизирует компонент, другой добавляет кнопку в макет после того, как компонент уже создан.

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