Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 09.05.2016, 17:35
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Есть ли декларативный аналог метода relayEvents()?
Есть ли возможность декларативно описать таблицу пересылки событий?

Пример как я это делаю императивно:

initComponent: function() {
		var me = this;
		me.callParent(arguments);
		me.relayEvents(me.down("settings-trolleylist"), "print-trolley-label-button-click");
	},
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.
Ответить с цитированием
  #2 (permalink)  
Старый 09.05.2016, 19:50
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Зачем это вообще делать? Используйте ViewController.
Ответить с цитированием
  #3 (permalink)  
Старый 09.05.2016, 20:11
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Мне нужно из дочерних видов вытащить события в корневой вид.

Я в основном контроллере ловлю это событие:

Ext.define("Element.controller.Settings", {
	
	extend: "Ext.app.Controller",
	alias: "controller.app.settings",
	
	control: {
		"settings": {
			"trolleylist-print-label-button-click": "onTrolleyListPrintLabelButtonClick"
		}
	},
	
	onTrolleyListPrintLabelButtonClick: function(trolleyListView, trolleyItem) {
		var me = this;
		var printer = me.getApplication().getController("Printer");
		printer.print("trolleyitem", "barcode", trolleyItem);
	}
	
});

Или вы намекаете что надо обойтись без relayEvents? И сделать в control селектор вида "settings > settings-trolleylist"?

.
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.

Последний раз редактировалось khusamov, 09.05.2016 в 20:33.
Ответить с цитированием
  #4 (permalink)  
Старый 09.05.2016, 20:22
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Если это делать в ViewController, то так что-ли сделать?

control: {
		"settings-trolleylist": {
			"print-label-button-click": function() {
				var args = Ext.Array.slice(arguments);
				args.unshift("trolleylist-print-label-button-click");
				this.getView().fireEvent.apply(this.getView(), args);
			}
		}
	},

Нагромождение какое-то вышло.

Жаль что в контроллере нет конфига relayEvents, чтобы просто настроить перенаправление событий и все.

.
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.

Последний раз редактировалось khusamov, 09.05.2016 в 20:37.
Ответить с цитированием
  #5 (permalink)  
Старый 09.05.2016, 20:28
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Или может так? Немного короче вышло:

init: function() {
		var me = this;
		var trolleyListView = me.getView().down("settings-trolleylist");
		me.getView().relayEvents(trolleyListView, ["print-label-button-click"], "trolleylist-");
	}
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.
Ответить с цитированием
  #6 (permalink)  
Старый 09.05.2016, 21:15
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Я намекаю на то, что не нужно вообще использовать Ext.app.Controller для ловли событий в видах - для этого есть ViewController. И relayEvents в таком случае совершенно не нужно.

Глобальные контроллеры в новых приложениях нужно использовать только для глобальных вещей, которых в принципе немного: события с сервера, общая шина коммуникаций, глобальная конфигурация и т.д.
Ответить с цитированием
  #7 (permalink)  
Старый 09.05.2016, 22:02
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

У меня в Ext.app.Controller организована печать на принтере (а именно прием заданий на печать, организация print-отчетов, подготовка данных к печати и т.п.). По-мойму вполне себе глобальная вещь. Зачем этот код плодить во всех видах?

Прием заданий я делаю путем ловли событий click из видов, в которых передается модель, которая затем поступает на вход отчета, и после обработки - в принтер. Это неправильно?
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.

Последний раз редактировалось khusamov, 09.05.2016 в 22:04.
Ответить с цитированием
  #8 (permalink)  
Старый 09.05.2016, 22:34
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Сообщение от khusamov Посмотреть сообщение
У меня в Ext.app.Controller организована печать на принтере (а именно прием заданий на печать, организация print-отчетов, подготовка данных к печати и т.п.). По-мойму вполне себе глобальная вещь. Зачем этот код плодить во всех видах?
Если печать у вас настолько сложна, что требует управления очередью и т.п., то в таком случае глобальный контроллер конечно же оправдан. В более простых случаях общий код можно включить в свой базовый класс ViewController, от которого потом наследовать ViewControllers для нужных видов.

Цитата:
Прием заданий я делаю путем ловли событий click из видов, в которых передается модель, которая затем поступает на вход отчета, и после обработки - в принтер. Это неправильно?
Технически такой подход допустим, и даже рекомендовался в версиях до 5.0, когда не было более удобных и менее проблематичных инструментов. Сейчас этот подход использовать настойчиво не рекомендуется, т.к. он чреват многими проблемами, для решения которых и предназначены ViewControllers.

В вашем случае я бы сделал так: ViewController ловит событие на дочерних компонентах и в свою очередь стреляет событие "printrequest" в контроллерном домене, передавая в аргументах объект со ссылкой на свою модель. Глобальный контроллер печати ловит события printrequest, берёт ссылку на модель, вытаскивает из неё нужные данные, ставит задание на печать и возвращает код подтверждения/ошибки.

Ext.define('My.view.FooPanel', {
    extend: 'Ext.panel.Panel',

    controller: 'foocontroller',

    viewModel: {
        ...
    },

    items: [{
        ...
    }],

    buttons: [{
        text: 'Печать',
        listeners: {
            click: 'onPrintButtonClick'
        }
    }]
});

Ext.define('My.view.FooPanelController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.foocontroller',

    onPrintButtonClick: function() {
        var options = {};

        options.viewModel = this.getViewModel();

        // Стреляем событие в домене Controller
        this.fireEvent('printrequest', options);

        if (options.success) {
            ...
        }
        else {
            Ext.Msg.alert('Ошибка печати', options.errorMsg);
        }
    }
});

Ext.define('My.controller.Print', {
    extend: 'Ext.app.Controller',

    listen: {
        controller: {
            '*': {
                printrequest: 'onPrintRequest'
            }
        }
    },

    onPrintRequest: function(options) {
        // Здесь *категорически* не стоит сохранять ссылку на модель,
        // это практически на 100% приведёт к проблемам.
        // Вытащили данные и больше модель не трогаем.
        var data = this.getDataFromViewModel(options.viewModel);

        if (this.spoolPrintJob(data)) {
            options.success = true;
        }
        else {
            options.errorMsg = '...';
        }
    }
});


Такой подход позволяет отделить мух от котлет и в т.ч. очень помогает при тестировании. Вместо сложного комплекса итераций вам достаточно будет протестировать контроллер Print на принятие событий и правильную обработку данных, и ViewController на выстреливание нужного события при нажатии на кнопку.
Ответить с цитированием
  #9 (permalink)  
Старый 09.05.2016, 23:43
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Вообще-то я имел ввиду под моделью экземпляр класса Ext.data.Model, но это наверное не существенно.

Цитата:
...и возвращает код подтверждения/ошибки.
Это разве допустимо? А если на событие printrequest подпишутся два обработчика???
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.
Ответить с цитированием
  #10 (permalink)  
Старый 10.05.2016, 03:31
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

А почему нет? :) На самом деле, это нормальный способ синхронной (и двусторонней!) передачи информации через события, безотносительно типа коммуницирующих сторон. Можно конечно и по-другому делать: контроллер Foo стреляет событие "printrequest", контроллер Print обрабатывает и в ответ стреляет событие "printresponse", которое Foo ловит. Или даже передавать ссылку на контроллер Foo в аргументах события, и т.п... Но я бы не рекомендовал так делать, т.к. можно легко насоздавать себе проблем с рекурсией, циклами событий и прочими прелестями односторонней синхронности. А уж про тестирование таких вариантов я просто молчу - фактически это будет означать взаимную зависимость обоих контроллеров друг от друга.

Важно понимать, что в предложенном решении инициатором запроса является ViewController, а глобальный контроллер лишь пассивно реагирует на запрос. Такой подход даёт вполне чистое концептуальное разграничение между модулями программы, которую в дальнейшем проще поддерживать и тестировать.

А если на событие printrequest подпишутся два обработчика, то объект options по возврату будет содержать потенциально конфликтную информацию. Но этот случай тоже довольно легко отловить:

onPrintRequest: function(options) {
    //<debug>
    if (options.success != null) {
        throw "Whoa there!";
    }
    //</debug>
}


На практике такое бывает довольно редко - мы же говорим о глобальных контроллерах, правда? Они ведь должны существовать в одном экземпляре, так ведь? И вы ведь это точно протестировали? ;)
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Есть ли в JavaScript аналог функции exec() из php? lorddarkside Общие вопросы Javascript 3 22.12.2010 12:37
Есть ли на JavaScript аналог PHP функции include?) FirstFrost Общие вопросы Javascript 3 13.07.2010 10:13
Есть ли аналог $_SERVER['DOCUMENT_ROOT'] ? .andreev Общие вопросы Javascript 4 20.11.2009 08:46
глюк форума Gvozd Сайт Javascript.ru 11 18.03.2009 14:37
Аналог WYSIWYG Aristarco Общие вопросы Javascript 3 09.11.2008 19:57