Добавление и измененение компонентов в дизайнере¶
Описание доступных типов и свойств компонентов¶
Все компоненты, используемые в дизайнере описаны в файле model-types-config.js. Внутри него находится объект typesConfig, полями которого являются доступные типы. Рассмотрим на примере ExtFormPanel:
formPanel: {
parent:'panel',
isContainer:true,
properties : {
id : {
defaultValue:'frm_formpanel',
isInitProperty:true,
isQuickEditable: true
},
layout: {
defaultValue:'form',
isInitProperty:true,
isQuickEditable: true
},
title: {
defaultValue:'',
isInitProperty:true,
isQuickEditable: true
},
url: {
defaultValue:''
},
fileUpload:{
defaultValue:false
},
urlShortName:{
defaultValue:'',
isQuickEditable:true
}
},
childTypesRestrictions:{
disallowed:['arrayStore','gridColumn','jsonStore','pagingToolbar']
},
toolboxData: {
category:'Containers',
text:'Form panel'
},
treeIconCls:'designer-formpanel'
}
parent:’panel’ - Ссылка на тип, который является предком текущего типа. Типы компонентов наследуют свойства друг друга(под свойствами в данном контексте подразумеваются объекты в properties, ограничения и другие объекты первого уровня вложенности не наследуются) Раз formPanel является наследником Panel она получит свойства layout, region, height, width и тд
isContainer:true - В случае если поле указано и равно true, то в компонент можно добавлять дочерние компоненты. Нужно отметить что под добавление дочерних в данном случае подразумевается чисто абстрактное условие, регламентирующее возможность иметь дочерние компоненты во внутренней структуре данных используемых дизайнером, и никак не связана напрямую с объектной моделью ExtJs. Так ComboBox имеет isContainer:true тк в него можно добавить подчиненный DataStore.
properties: {} - Вложенные свойства это те поля что доступны для редактирования пользователю.
defaultValue:’form’ - обязательное поле для каждого свойства типа. По типу(javascript типу) определеяется редактор. К примеру height и width у контенейров обязан быть числом, и поэтому defaultValue:0 и редактироваться будет NumberField’ом.
isInitProperty:true - Необязательное поле. Если установлено то при создании нового экземпляра поле будет проинициализировано. Типичный пример тайтлы у всего что можно
isQuickEditable:true - Необязательное поле. True - свойство появиться в редакторе быстрых свойств
propertyType:’enum’ - Необязательное поле. Если не указано, то Javascript тип свойства будет определен по значению defaultValue. В данный момент обрабатываюются значения ‘enum’ и ‘object’ Значения перечисления обрабатываютcя в файле property-editor.js Для значения ‘object’ - вводимый пользователем текст будет про’eval’ен, это нужно для вложенных объектов. Значения перечислений прописываются в model-types.js
isNotEditable:true - Необязательное поле. Используется когда нужно проинизализировать что-то в экземпляре объекта, но не давать пользователю рукам это что-то перебить. Пример TabPanel, дабы не унаследовать от Panel значение layout по умолчанию ‘auto’
childTypesRestrictions - Ограничения для подчиненных объектов. Состоит из трех массивов со строковыми названиями типов. allowed - то что можно добавлять, disallowed - то что нельзя, single - одиночные типы Каждый из массивов может отсутствовать, в таком случае условие игнорируется при проверке. К примеру disallowed:undefined, allowed:[‘panel’], single:[‘panel’] - к текущему компоненту можно добавить ровно одну панель
toolboxData - Информация для панели инструментов. Может отсутствовать
treeIconCls - Очевидно иконка типа компонента. Необязательное поле
Визуальное отображение компонентов¶
Код рисующий штуки на экране уютно расположился в файле ui.js Для рисования использовался хитрый паттерн “Посетитель” Для рисования нужно добавить новую функцию объекту mapObject, имя которой совпадало бы с названием типа определенного в файле конфигов. Если функция не определена - ничего не случится. Просто компонент не нарисуется:
comboBox:function(model, cfg) {
var store = undefined;
//попробуем найти стор
for (var i = 0; i < model.childNodes.length; i++) {
if (model.childNodes[i].attributes.type == 'arrayStore') {
store = new Ext.data.ArrayStore(
Ext.apply({
fields:['id',model.attributes.properties.displayField]
},model.childNodes[i].attributes.properties)
);
}
}
//или создадим пустой
if (!store) {
store = new Ext.data.Store({
autoDestroy:true
});
}
return Ext.apply( cfg , {
store:store,
mode:'local',
xtype:'combo'
});
}
В аргументе model передается объект внутренней модели дизайнера, через него можно получить доступ к родительскому компоненту или к дочерним. cfg - готовый объект конфига со свойствами отредактированными пользователем. Для простых случаев, например, textField достаточно в объект конфига добавить xtype для того чтобы экст корректно создал визуальный компонент. Можно не использовать xtype, и создавать инстансы классов. В примере выше рассамтривается создание комбобокса. Чаще всего для дизайна нам не требуется сложное поведение компонентов, и поэтому можно создать ограниченую болванку, которой достаточно чтобы послужить отражением более сложного компонента(или закрыть от активации какое то поведение, как правило обмен данными с севрером)
Сериализация/десериализация¶
Код находиться в файле transfer.js В подавляющих случаях туда не нужно ничего добавлять. Но иногда, когда у компонентов есть компоненты не принадлежащие items, приходится добавлять всячески исключения. Пример тому свойство store, или массив columns у грида. Смотреть нужно на объект childPropertyObjects. В массивы добавляются свойства для особенной десериализации, в функции типы требующие сериалзиации как-то поособенному.
Серверный маппинг¶
Для того, чтобы код успешно серриализовался в python код и обратно нужно добавлять компоненты в серверный маппинг.
- Серверный маппинг находится в файле m3_designer/ide/mapping.json. Рассматорим пример маппинга::
- {
- “class”: {
- “objectGrid”: “ExtObjectGrid”
}, “config”: {
“urlNew”:”url_new” ,”urlEdit”:”url_edit” ,”urlDelete”:”url_delete” ,”urlData”:”url_data” ,”rowIdName”:”row_id_name” ,”columnParamName”:”column_param_name” ,”allowPaging”:”allow_paging” ,”localEdit”: “local_edit”
- ,”urlDataShortName”: {
- “type”:”shortname” ,”value”:”url_data”
} ,”urlEditShortName”: {
“type”:”shortname” ,”value”:”url_edit”} ,”urlDeleteShortName”:{
“type”:”shortname” ,”value”:”url_delete”} ,”urlNewShortName”:{
“type”:”shortname” ,”value”:”url_new”}
} ,”parent”: “gridPanel”
}
Объект class говорит о том, что клиентский класс objectGrid будет маппиться в серверный класс ExtObjectGrid. Конфиг объектов данного класса так же маппится из клиенского кода urlNew в серверный код url_new и наоборот. Могут быть сложные свойтсва, такие свойства помечаются свойством “type”, например объект “shortname”, имеющий свойство “create” будет отображен в серверный поиска шортнейма - instanse.attr = urls.get_url(‘create’)