2012-06-22 2 views
1

Я новичок в extJS, и, может быть, я просто не знаю правильной стратегии, поэтому вы можете сказать мне лучшее решение, если хотите.make subelements слушать событие extJS

Что я пытаюсь: У меня есть сетка extJS. В двойном клике должен появиться контейнер ExtJS Window (для подробных настроек), в котором есть несколько вкладок. В окне есть функция, позволяющая установить идентификатор элемента с щелчком. Каждая вкладка в окне также нуждается в этом идентификаторе. Поэтому я хочу сообщить каждому контейнеру табуляции через событие об измененном идентификаторе, когда идентификатор изменен в контейнере окна.

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

Может быть, вы можете понять мою проблему лучше, если вы посмотрите на мой исходный код:

Окно (setCustomerId() и шоу() вызывается, когда дважды щелкнув на элементе сетки)

Ext.define('myApp.path.view.Edit', { 
extend: 'Ext.window.Window', 
alias: 'widget.myEdit', 

title: 'Edit', 
height: 500, 
width: 1000, 
layout: 'fit', 
closeAction: 'hide', 

/** 
* Initialize my custom event 
*/ 
initComponent: function() { 
    this.addEvents('customerChanged'); 

    this.callParent(); 
}, 

/** 
* Sets the current customerId and fires a customerChanged event 
* @param {Number} customerId 
*/ 
setCustomerId: function(customerId) { 
    this.customerId = customerId; 
    this.fireEvent('customerChanged', this.customerId); 
}, 

/** 
* create a container for the editor tabs 
*/ 
items: [{ 
    xtype: 'tabpanel', 
    items: [ 
     { 
      xtype: 'myTab' 
     } 
    ] 
}] 
}) 

вкладка пример

Ext.define('myApp.path.view.myTab', { 
extend: 'Ext.container.Container', 
alias: 'widget.myTab', 

title: 'Customer', 
layout: 'fit', 

/** 
* Listen to my custom event 
* PROBLEM: works, but only after the window has been displayed one time 
*/ 
afterRender: function() { 
    this.findParentByType('window').addListener("customerChanged", this.onCustomerChanged) 
    this.callParent(); 
}, 

/** 
* Listen to my custom event 
* PROBLEM: doesn't work, findParentByType('window') is undefined 
*/ 
initComponent: function() { 
    this.findParentByType('window').addListener("customerChanged", this.onCustomerChanged) 
    this.callParent(); 
}, 

onCustomerChanged: functio() {} 

}) 

Надеюсь, ты сможешь понять мое намерение. Спасибо!

+0

Совершенно правильно, что функция 'afterRender' вызывается _after_, окно было визуализировано (и initComponent вызывается сразу после его создания, прежде чем он будет визуализирован или добавлен). Кстати, что ваши вкладки нужно знать, прежде чем окно даже будет создано? Я не вижу намерения, что вам нужно id_before_ добавлено ваше окно;) –

+0

Мне не нужен идентификатор, прежде чем вкладка будет выделена. Моя проблема заключалась в том, что я хотел получать информацию каждый раз, когда изменяется идентификатор, и, конечно, когда окно открывается в первый раз. Но, как упоминал Ник, событие активации - лучший способ просто смотреть каждый раз, если идентификатор изменился. – philsch

ответ

0

Не знает код itemdblclick события сетки (это будет полезно), но я вижу, что это что-то вроде:

itemdblclick: function(v, m) { 
    var id = m.get('id'); 

    //think you are not created a window each time, having the "closeAction: 'hide'" in the code 
    //if for simplicity sake, for sure it should not be here 
    if (!this.detailsWin) { 
     this.detailsWin = Ext.create('myApp.path.view.Edit'); 
    } 

    //you set the ID and after it shows the window 
    //that is why for the first time event listener is bot working 
    this.detailsWin.setCustomerId(id); 

    //showing the window 
    this.detailsWin.show();  
} 

Если это так, то вам нужно позвонить setCustomerId после show:

this.detailsWin.show(); 
    this.detailsWin.setCustomerId(id); 

или просто переопределить метод шаблона внутри окна:

/** 
* @template 
*/ 
onShow: function() { 
    //firing the event 
    //should be checking here if the ID was really changed 
    this.fireEvent('customerChanged', this.customerId); 

    //call parent to show the window 
    this.callParent(arguments); 
} 

, то вы можете запустить showsetCustomerId в любом порядке.

Или вызовите метод показа окна с помощью функции обратного вызова:

this.detailsWin.show(null, function(){ 
    this.setCustomerId(id); 
}); 

, но убедитесь, что окно является модальным, поскольку это окно не является модальным и показывается вам будет щелкая строки GRID, принявшего его открытия обратного вызова функция не будет работать.

Проблема.

Btw, вы должны заметить, что с использованием такого механизма и с несколькими вкладками в окне. Например, A, B, C, имеющие A как активную вкладку. Вкладки B и C не будут прослушивать событие customerChanged (не иметь идентификатора клиента) до тех пор, пока они не будут отображены. Итак, когда окно открывается в первый раз, будет вызываться вкладка A onCustomerChanged, а вкладка A будет знать об идентификаторе, но вкладки B и C ничего не знают об этом (потому что они пока не отображаются, пока вы не активируете/не открываете их и их слушатели событий onCustomerChanged не использовались). Это проблема такого подхода.

Отображение окна, в котором отображаются все вкладки, будет работать, но это не лучший подход для внесения изменений для всех отображаемых вкладок на них, особенно с большим количеством компонентов на каждой вкладке, загружающей данные и т. Д. Пользователю может понадобиться например, только одна вкладка из 10, чтобы что-то сделать, и слишком сложно сделать изменения для всех уже отображенных вкладок, запускающих событие.

Плюс dbl, щелкнув одну и ту же запись в сетке, откроет одно и то же окно 2 раза с тем же идентификатором - так что лучше проверить, был ли ID изменен, прежде чем запускать событие.

Чтобы решить вышеуказанную проблему, я предлагаю использовать событие activate внутри вкладок, имеющих внутри каждой вкладки собственное свойство clientID для отслеживания изменений и, конечно, метод получения текущего идентификатора, переданного в окно. Для этой цели вы можете использовать свой базовый класс вкладки, который расширяется каждым классом табуляции, используя внутри окна или используя mixin, чтобы обеспечить общие функциональные возможности для вкладок. Плюс обработать активную (запустив тот же общий код для вкладки) вкладку в окне, которое отображается, если вы хотите сохранить последнюю активную вкладку (из предыдущего окна времени было открыто), потому что событие activate не будет запущено при открытии окна или просто установите активную вкладку каждый раз, когда окно отображается с помощью метода tabpanel setActiveTab, лучше всего переопределить метод шаблона onShow. Разумеется, удаляем добавление прослушивателей событий из вкладок.

+0

Большое спасибо за этот подробный ответ. Событие активации - лучший способ решить эту проблему. Теперь я создал новый класс табуляции, который просто проверяет, изменился ли идентификатор, обратившись к моему оконному объекту extJs, а затем вызовите функцию, которую должен выполнить каждый расширяемый класс. – philsch

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