Наскоро програмистката ми практика ме сблъска с един нетривиален проблем относно ExtJS 4.2. Предупреждавам, че този пост изисква много добро познаване на фреймуърка за да се извлекат каквито и да е ползи от него.

Та проблемът бе следният: има инстанция на RowEditing плъгина, в който някои от клетките зависят от стойностите на други клетки и би било хубаво да се изменят динамично, т.е. on the fly при въвеждане на стойности. И започна интересната част, която ми отне половин ден усилия и удовлетворителен край.

Първо какво представлява rowEditor-a? Оказа се една форма, където клетките, които не могат да се редактират, са displayfield-ове. Реших проблема, като към всички полета във формата вързах event listener-и, активирането на които да води до повторно пресмятане на зависимите полета. Понеже нямаше как да изпълнявам този код само веднъж при инициализирането на едитора, използвах едно фиктивен event handler на формата. Какво имам предвид – Row Editor има четири събития, които обаче се викат при всяко негово отваряне. Аз използвам beforeedit събитието за да вържа празна функция на формата на едитора за събитието ‘fieldvaliditychange’, което не се използва и няма какво да го предизвика за този компонент. Този event handler ми служи като флаг, за да може същинското връзване на event handler-и да се случи веднъж при първото извикване на row editor-а.

И така, остава чистата механика или това точно кои компоненти и функции да се използват, за да се достигне до желания резултат. Начинът не е описан в документацията или на “избираемо място” в интернет. Кодът с коментари:

beforeedit: function(editor, context){{
    //gets the form of the row editor, which holds the updated values
    var form = editor.editor.getForm();
    if(form.events['fieldvaliditychange'] === undefined){
        console.log('Row editing formula updating on the fly initialized.');
        //sets empty event handler to indicate the actual ones have been assigned
        form.on('fieldvaliditychange', function(){});
        //set an event handler for the change event for any of the form fields
        form.getFields().items.forEach(function(f){ f.on('change', function(){
            //for each grid column if there is a formula, update it
            context.grid.columnManager.getColumns().forEach(function(c){
                var columnName = c.dataIndex;
                //if there is a formula there is a function
                if(c.updateRowEditorFormulaValue){
                    var fieldToUpdate = form.getFields().items['find'](function(f){
                        if(f.getName() === columnName){
                            return f;
                        }
                    });
                                            
                    var newValue = c.updateRowEditorFormulaValue(form.getFields().items, columnName);
                    fieldToUpdate.setValue(newValue);
                }
            })
        })});
    }
}

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

73 + = 78