воскресенье, 21 июля 2013 г.

Слушаем кнопки в Ext.form.field.HtmlEditor

В режиме изменения HTML-кода перестаёт генерироваться событие dirtychange. Из-за этого невозможно разблокировать кнопку сохранения формы. Проблема показана на видео:



Как справиться с таким затруднением, не прибегая к средствам чёрной магии? Как заставить коробочный компонент ExtJs генерировать новые события? Ниже представлен вариант решения.

Попутно замечу, что белая магия не использует костыли для достижения необходимого результата. Только волшебные палочки. Значит, мы остаёмся в рамках MVC и определяем обработчик в контроллере. Мы также не используем незадокументированные свойства объектов ExtJs (например, textareaEl).

Просто ждём, пока не отобразится HTML-редактор. Когда он отобразится, будет сгенерировано событие render. В обработчике этого события находим в DOM текстовое поле. На его событие keyup навешиваем проверку изменений. В документации написано, что при обнаружении изменений будет распространено событие dirtychange. Наша проблема будет решена.

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


Представление (V)


Ext.define('Admin.view.HtmlEditor', {
   
    extend: 'Ext.form.Panel',
   
    alias: 'widget.app-html-editor',
   
    trackResetOnLoad: true, // позволяет следить за изменениями в полях формы через событие dirtychange
   
    layout: 'fit',
   
    items: [
        {
            xtype: 'htmleditor',
            itemId: 'html-editor-field',
            name: 'html'
        }
    ]


});



Контроллер (C)


Ext.define('Admin.controller.HtmlEditorController', {
   
    extend: 'Ext.app.Controller',

    init: function() {
       
        this.listen({
            component: {
                'app-html-editor': {
                    dirtychange: this.onDirtyChange
                },
                'app-html-editor [itemId="html-editor-field"]': {
                    render: this.listenToKeyEvents
                }

            }
        });
       
    },
   
    listenToKeyEvents: function(htmlEditorField) {
       
        htmlEditorField.getEl().down('textarea').on('keyup', function() {
           
            htmlEditorField.checkDirty();
           
        });
       
    },

   
    onDirtyChange: function(basicForm, isDirty) {

        var formPanel = basicForm.owner;
       
        var menuButton = formPanel.down('[itemId="menu-button"]');
        var saveButton = formPanel.down('[itemId="save-button"]');
        var cancelButton = formPanel.down('[itemId="cancel-button"]');
       
        if (isDirty) {
           
            menuButton.disable();
            saveButton.enable();
            cancelButton.enable();
           
        } else {
           
            menuButton.enable();
            saveButton.disable();
            cancelButton.disable();
           
        }
       
    }

 
});




Проверим, как это работает.