Прослушивание событий между компонентами разных view
Всем привет!
Как обычно слушать события между контроллерами я уже знаю. Прописываем id для контроллера: id: 'employees-window1', Там же вызываем событие: onCancelClick: function () { this.fireEvent('close'); }, В нужном контроллере слушаем события заданного контроллера (селектор по id): listen : { controller : { '#employees-window1' : { close : 'onCancelClick' } } }, Это работает если у нас 2 контроллера объявлены. Но по идее нам 2й контроллер и не нужен, т к мы можем вызвать событие и на обработчике кнопки: buttons: [{ text: 'Сохранить', handler: 'onSaveClick' }, { text: 'Отмена', handler: function() { this.fireEvent('close'); } }] Но вот как слушать событие компонента? в данном случае формы внутри Window. Нашел, что можно прописывать в `listen` еще и `component`: http://docs.sencha.com/extjs/6.2.0/m...tml#cfg-listen Как только не пробовал с заданием id для window, например, так: listen : { component : { '#employees-window1 > button[text=Отмена]' : { close : 'onCancelClick' } } }, Не работает! Вообще возможно так делать как я описал? |
Можно, но незачем. Используйте ViewController, они специально предназначены для отслеживания событий в своих view, включая иерархию. В данном случае вам нужен только один VC, в окне:
Ext.define('MyApp.view.WindowController', { extend: 'Ext.app.ViewController', alias: 'controller.windowcontroller', onSaveClick: function() { ... }, onCancelClick: function() { ... } }); Ext.define('MyApp.view.Window', { extend: 'Ext.window.Window', requires: [ 'MyApp.view.WindowController', ], controller: 'windowcontroller', items: [{ xtype: 'form', ... buttons: [{ text: 'Сохранить', handler: 'onSaveClick' }, { text: 'Отмена', handler: 'onCancelClick' }] }] }); |
В том и дело, что я хочу один контроллер на оба View. Я уже писал о том, что хочу сделать тут, реализовал это с помощью событий. Сейчас главный ViewController слушает события другого (2й только делает fireEvent по кликам на кнопки), в итоге получаем единый this контекст и отсутствие проблем с постоянной выборкой view, viewmodel итп
Я мог бы обойтись без 2го viewController вообще, если бы знал каким образом слушать события определенного View. В этом и состоит мой вопрос: как это сделать? :) |
Можно во вью обьявлять метод контроллера который будет обрабатывать данное событие. Например у кнопки :
handler:'onbuttonclick'. например сть главный вьюпорт и у него контроллер. в этом контроллере можно этот метод прописать. Экcт будет искать его по всей иерархии контроллеров пока не найдет. НО это не сработает внутри окон. они не в иерархии вьюпорта. Есть ещё система глобальных событий экста. например можно в каком нибудь месте сделать так: Ext.GlobalEvents.fireEvent('EventName', .., .., ..) А в контроллере: Ext.on('EventName', this.method, this); Но по логике так не правильно. Так как сильно затрудняет поиск что откуда взялось. |
Цитата:
Цитата:
Если вам нужно организовать общение между совершенно разрозненными компонентами, которые не входят в общую иерархию, то это другой случай. Можно стрелять события по домену controller из одного VC и слушать в другом VC, или пропускать их через брокера в виде глобального контроллера (или VC самого Viewport). Тут уже зависит от задачи и предпочтений. |
Задача избавиться от 2го VC, который навешан на модальное окно с формой, потому что в нем ничего нет кроме 2-х вызовов fireEvent.
А в главном VC (грид) у меня получается слушать лишь другой VC (модального окна) через прописывание controller. При прописывании прослушки component почему-то не работает. Иерархии тут, увы, нет, потому что если я добавляю форму как дочку от Грида, то появляется она поверх этого грида, а не viewport, как мне нужно. Поэтому я добавляю окно так: this.dialog = main.add( //<--- main — это главный View И обращаюсь к нему позже с помощью this.dialog. Если прописать тупо `controller: ` у окна такой же, как и у Грида, то работать вся конструкция не станет, т к будет 2й экземпляр одного объекта и все привязанные ранее к this объекты уже не будут доступны. |
Теперь понял, спасибо. По поводу маскирования отвечу подробнее в другой ветке, но что касается ViewController, то лучше и проще добавить окно с формой как дочку grid.
|
Цитата:
Сделал gif-ку с разными размерами браузера, чтобы было понятнее как это все выглядит: http://i.imgur.com/ZHg9ak8.gifv p.s. На синтетических примерах KitchenSink итп работает все отлично, т к там кроме грида с записями обычно ничего и нет ;) |
Да, я поиграл с вариантами и получается, что модальную маску никак не заставить работать нужным образом. Если окно является дочкой другого компонента, то ZIndexManager маскирует родительский компонент и это никак не обойти, поскольку зашито в приватных методах. :/
Поэтому тут два варианта: либо неправильная маскировка, либо "лишний" ViewController. Думайте сами, решайте сами. |
В нагрузку для этой темы есть интересная маленькая познавательная статейка - Declarative Listeners vs. Control
|
Часовой пояс GMT +3, время: 15:06. |