Показать сообщение отдельно
  #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 на выстреливание нужного события при нажатии на кнопку.
Ответить с цитированием